@@ -209,39 +209,38 @@ impl CompressedEdwardsY {
209209 ///
210210 /// Returns `None` if the input is not the \\(y\\)-coordinate of a
211211 /// curve point.
212+ // See https://www.rfc-editor.org/rfc/rfc8032.html#section-5.2.3.
212213 pub fn decompress_unchecked ( & self ) -> CtOption < EdwardsPoint > {
213214 // Safe to unwrap here as the underlying data structure is a slice
214215 let ( sign, b) = self . 0 . split_last ( ) . expect ( "slice is non-empty" ) ;
215216
216217 let mut y_bytes: [ u8 ; 56 ] = [ 0 ; 56 ] ;
217218 y_bytes. copy_from_slice ( b) ;
218-
219- // Recover x using y
219+ // TODO: this should fail if unreduced.
220220 let y = FieldElement :: from_bytes ( & y_bytes) ;
221- let yy = y. square ( ) ;
222- let dyy = FieldElement :: EDWARDS_D * yy;
223- let numerator = FieldElement :: ONE - yy;
224- let denominator = FieldElement :: ONE - dyy;
225221
226- let ( mut x, is_res) = FieldElement :: sqrt_ratio ( & numerator, & denominator) ;
222+ // x^2 = (y^2 - 1) / (d y^2 - 1)
223+ let yy = y. square ( ) ;
224+ let u = yy - FieldElement :: ONE ;
225+ let v = FieldElement :: EDWARDS_D * yy - FieldElement :: ONE ;
226+ let ( mut x, is_square) = FieldElement :: sqrt_ratio ( & u, & v) ;
227227
228228 // Compute correct sign of x
229229 let compressed_sign_bit = Choice :: from ( sign >> 7 ) ;
230230 let is_negative = x. is_negative ( ) ;
231231 x. conditional_negate ( compressed_sign_bit ^ is_negative) ;
232232
233- CtOption :: new ( AffinePoint { x, y } . to_edwards ( ) , is_res )
233+ CtOption :: new ( AffinePoint { x, y } . to_edwards ( ) , is_square )
234234 }
235235
236236 /// Attempt to decompress to an `EdwardsPoint`.
237237 ///
238238 /// Returns `None`:
239239 /// - if the input is not the \\(y\\)-coordinate of a curve point.
240- /// - if the input point is not on the curve.
241240 /// - if the input point has nonzero torsion component.
242241 pub fn decompress ( & self ) -> CtOption < EdwardsPoint > {
243242 self . decompress_unchecked ( )
244- . and_then ( |pt| CtOption :: new ( pt, pt. is_on_curve ( ) & pt . is_torsion_free ( ) ) )
243+ . and_then ( |pt| CtOption :: new ( pt, pt. is_torsion_free ( ) ) )
245244 }
246245
247246 /// View this `CompressedEdwardsY` as an array of bytes.
0 commit comments