@@ -319,10 +319,6 @@ impl<'a> Square for &'a FieldElement {
319319impl < ' a > Half for & ' a FieldElement {
320320 type Output = FieldElement ;
321321 /// Give the half of the FieldElement value (mod l).
322- ///
323- /// This function SHOULD ONLY be used with even
324- /// `FieldElements` otherways, can produce erroneus
325- /// results.
326322 fn half ( self ) -> FieldElement {
327323 self * & constants:: INVERSE_MOD_TWO
328324 }
@@ -337,6 +333,7 @@ impl<'a, 'b> Pow<&'b FieldElement> for &'a FieldElement {
337333 ///
338334 /// Schneier, Bruce (1996). Applied Cryptography: Protocols,
339335 /// Algorithms, and Source Code in C, Second Edition (2nd ed.).
336+ /// TODO: Review the while with the different half implementations.
340337 fn pow ( self , exp : & ' b FieldElement ) -> FieldElement {
341338 let ( zero, one) = ( FieldElement :: zero ( ) , FieldElement :: one ( ) ) ;
342339 let mut base = * self ;
@@ -405,15 +402,15 @@ impl<'a> ModSqrt for &'a FieldElement {
405402 let mut s = zero;
406403 while q. is_even ( ) {
407404 s = s + one;
408- q = q. half ( ) ;
405+ q = q. fast_even_half ( ) ;
409406 }
410407
411408 // Select a z which is a quadratic non resudue modulo p.
412409 // We pre-computed it so we know that 6 isn't QR.
413410 let mut c = six. pow ( & q) ;
414411
415412 // Search for a solution.
416- let mut x = self . pow ( & ( q + one) . half ( ) ) ;
413+ let mut x = self . pow ( & ( q + one) . fast_even_half ( ) ) ;
417414 let mut t = self . pow ( & q) ;
418415 let mut m = s;
419416
@@ -514,6 +511,7 @@ fn m(x: u64, y: u64) -> u128 {
514511}
515512
516513impl FieldElement {
514+
517515 /// Construct zero.
518516 pub const fn zero ( ) -> FieldElement {
519517 FieldElement ( [ 0 , 0 , 0 , 0 , 0 ] )
@@ -670,6 +668,33 @@ impl FieldElement {
670668 res
671669 }
672670
671+ /// Returns the half of an **EVEN** `FieldElement`.
672+ ///
673+ /// This function performs almost 4x faster than the
674+ /// `Half` implementation but SHOULD be used carefully.
675+ pub fn fast_even_half ( self ) -> FieldElement {
676+ assert ! ( self . is_even( ) ) ;
677+ let mut res = self ;
678+ let mut remainder = 0u64 ;
679+ for i in ( 0 ..5 ) . rev ( ) {
680+ res[ i] = res[ i] + remainder;
681+ match ( res[ i] == 1 , res[ i] . is_even ( ) ) {
682+ ( true , _) => {
683+ remainder = 4503599627370496u64 ;
684+ }
685+ ( _, false ) => {
686+ res[ i] = res[ i] - 1u64 ;
687+ remainder = 4503599627370496u64 ;
688+ }
689+ ( _, true ) => {
690+ remainder = 0 ;
691+ }
692+ }
693+ res[ i] >>= 1 ;
694+ }
695+ res
696+ }
697+
673698 /// Given a FieldElement, this function evaluates if it is a quadratic
674699 /// residue (mod l).
675700 ///
@@ -683,6 +708,7 @@ impl FieldElement {
683708 ///
684709 /// `0` -> `Input (mod l) == 0`. Not implemented since you can't pass
685710 /// an input which is multiple of `FIELD_L`.
711+ /// TODO: Refactor minus_one.half by a constant.
686712 pub fn legendre_symbol ( & self ) -> Choice {
687713 let res = self . pow ( & FieldElement :: minus_one ( ) . half ( ) ) ;
688714 res. ct_eq ( & FieldElement :: minus_one ( ) ) ^ Choice :: from ( 1u8 )
@@ -865,25 +891,25 @@ impl FieldElement {
865891 match ( u. is_even ( ) , v. is_even ( ) , u > v, v >= u) {
866892 // u is even
867893 ( true , _, _, _) => {
868- u = u. half ( ) ;
894+ u = u. fast_even_half ( ) ;
869895 s = s * two;
870896 }
871897 // u isn't even but v is even
872898 ( false , true , _, _) => {
873- v = v. half ( ) ;
899+ v = v. fast_even_half ( ) ;
874900 r = r * two;
875901 }
876902 // u and v aren't even and u > v
877903 ( false , false , true , _) => {
878904 u = u - v;
879- u = u. half ( ) ;
905+ u = u. fast_even_half ( ) ;
880906 r = r + s;
881907 s = s * two;
882908 }
883909 // u and v aren't even and v > u
884910 ( false , false , false , true ) => {
885911 v = v - u;
886- v = v. half ( ) ;
912+ v = v. fast_even_half ( ) ;
887913 s = r + s;
888914 r = r * two;
889915 }
0 commit comments