@@ -338,27 +338,6 @@ impl FieldElement {
338
338
( inv_sqrt_x * u, zero_u | is_res)
339
339
}
340
340
341
- /// Computes the square root ratio of two elements
342
- ///
343
- /// The difference between this and `sqrt_ratio` is that
344
- /// if the input is non-square, the function returns a result with
345
- /// a defined relationship to the inputs.
346
- pub ( crate ) fn sqrt_ratio_i ( u : & FieldElement , v : & FieldElement ) -> ( FieldElement , Choice ) {
347
- const P_MINUS_THREE_DIV_4 : U448 = U448 :: from_be_hex (
348
- "3fffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffff" ,
349
- ) ;
350
- let u = u. 0 ;
351
- let v = v. 0 ;
352
-
353
- let r = u * ( u * v) . pow ( & P_MINUS_THREE_DIV_4 ) ;
354
- let check = v * r. square ( ) ;
355
- let was_square = check. ct_eq ( & u) ;
356
-
357
- let mut r = FieldElement ( r) ;
358
- r. conditional_negate ( r. is_negative ( ) ) ;
359
- ( r, was_square)
360
- }
361
-
362
341
pub ( crate ) fn map_to_curve_elligator2 ( & self ) -> AffinePoint {
363
342
let mut t1 = self . square ( ) ; // 1. t1 = u^2
364
343
t1 *= Self :: Z ; // 2. t1 = Z * t1 // Z * u^2
@@ -382,38 +361,49 @@ impl FieldElement {
382
361
AffinePoint { x, y }
383
362
}
384
363
364
+ // See https://www.shiftleft.org/papers/decaf/decaf.pdf#section.A.3.
365
+ // Implementation copied from <https://sourceforge.net/p/ed448goldilocks/code/ci/e5cc6240690d3ffdfcbdb1e4e851954b789cd5d9/tree/src/per_curve/elligator.tmpl.c#l28>.
385
366
pub ( crate ) fn map_to_curve_decaf448 ( & self ) -> TwistedExtendedPoint {
386
367
const ONE_MINUS_TWO_D : FieldElement =
387
368
FieldElement ( ConstMontyType :: new ( & U448 :: from_u64 ( 78163 ) ) ) ;
388
369
389
370
let r = -self . square ( ) ;
390
- let u0 = Self :: EDWARDS_D * ( r - Self :: ONE ) ;
391
- let u1 = ( u0 + Self :: ONE ) * ( u0 - r) ;
392
-
393
- let rhs = ( r + Self :: ONE ) * u1;
394
- let ( v, was_square) = Self :: sqrt_ratio_i ( & ONE_MINUS_TWO_D , & rhs) ;
395
-
396
- let mut v_prime = self * v;
397
- v_prime. conditional_assign ( & v, was_square) ;
398
- let mut sgn = Self :: MINUS_ONE ;
399
- sgn. conditional_negate ( was_square) ;
400
-
401
- let s = v_prime * ( r + Self :: ONE ) ;
402
- let s2 = s. square ( ) ;
403
- let s_abs = Self :: conditional_select ( & s, & s. neg ( ) , s. is_negative ( ) ) ;
404
-
405
- let w0 = s_abs + s_abs;
406
- let w1 = s2 + Self :: ONE ;
407
- let w2 = s2 - Self :: ONE ;
408
- let w3 = v_prime * s * ( r - Self :: ONE ) * ONE_MINUS_TWO_D + sgn;
409
-
410
- EdwardsPoint {
411
- X : w0 * w3,
412
- Y : w2 * w1,
413
- Z : w1 * w3,
414
- T : w0 * w2,
415
- }
416
- . to_twisted ( )
371
+
372
+ let a = r - Self :: ONE ;
373
+ let b = a * Self :: EDWARDS_D ;
374
+ let a = b + Self :: ONE ;
375
+ let b = b - r;
376
+ let c = a * b;
377
+
378
+ let a = r + Self :: ONE ;
379
+ let n = a * ONE_MINUS_TWO_D ;
380
+
381
+ let a = c * n;
382
+ let ( b, square) = a. inverse_square_root ( ) ;
383
+ let c = Self :: conditional_select ( self , & Self :: ONE , square) ;
384
+ let e = b * c;
385
+
386
+ let mut a = n * e;
387
+ a. conditional_negate ( !Choice :: from ( a. 0 . retrieve ( ) . bit ( 0 ) ) ^ square) ;
388
+
389
+ let c = e * ONE_MINUS_TWO_D ;
390
+ let b = c. square ( ) ;
391
+ let e = r - Self :: ONE ;
392
+ let c = b * e;
393
+ let mut b = c * n;
394
+ b. conditional_negate ( square) ;
395
+ let b = b - Self :: ONE ;
396
+
397
+ let c = a. square ( ) ;
398
+ let a = a + a;
399
+ let e = c + Self :: ONE ;
400
+ let T = a * e;
401
+ let X = a * b;
402
+ let a = Self :: ONE - c;
403
+ let Y = e * a;
404
+ let Z = a * b;
405
+
406
+ TwistedExtendedPoint { X , Y , Z , T }
417
407
}
418
408
}
419
409
0 commit comments