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