11//! Lucas primality test.
2- use crypto_bigint:: { Integer , Monty , Odd , Square , Word } ;
2+ use crypto_bigint:: { Integer , Limb , Monty , Odd , Square , Word } ;
33
44use super :: {
55 gcd:: gcd_vartime,
@@ -161,7 +161,7 @@ impl LucasBase for BruteForceBase {
161161 // Since the loop proceeds in increasing P and starts with P - 2 == 1,
162162 // the shared prime factor must be P + 2.
163163 // If P + 2 == n, then n is prime; otherwise P + 2 is a proper factor of n.
164- let primality = if n. as_ref ( ) == & T :: from ( p + 2 ) {
164+ let primality = if n. as_ref ( ) == & T :: from_limb_like ( Limb :: from ( p + 2 ) , n . as_ref ( ) ) {
165165 Primality :: Prime
166166 } else {
167167 Primality :: Composite
@@ -182,6 +182,7 @@ fn decompose<T: Integer>(n: &Odd<T>) -> (u32, Odd<T>) {
182182 // Need to be careful here since `n + 1` can overflow.
183183 // Instead of adding 1 and counting trailing 0s, we count trailing ones on the original `n`.
184184
185+ let one = T :: one_like ( n) ;
185186 let s = n. trailing_ones_vartime ( ) ;
186187 let d = if s < n. bits_precision ( ) {
187188 // The shift won't overflow because of the check above.
@@ -190,10 +191,10 @@ fn decompose<T: Integer>(n: &Odd<T>) -> (u32, Odd<T>) {
190191 n. as_ref ( )
191192 . overflowing_shr_vartime ( s)
192193 . expect ( "shift should be within range by construction" )
193- . checked_add ( & T :: one ( ) )
194+ . checked_add ( & one)
194195 . expect ( "addition should not overflow by construction" )
195196 } else {
196- T :: one ( )
197+ one
197198 } ;
198199
199200 ( s, Odd :: new ( d) . expect ( "`d` should be odd by construction" ) )
@@ -293,6 +294,9 @@ pub fn lucas_test<T: Integer>(
293294 // R. Crandall, C. Pomerance, "Prime numbers: a computational perspective",
294295 // 2nd ed., Springer (2005) (ISBN: 0-387-25282-7, 978-0387-25282-7)
295296
297+ // A word-to-big integer conversion helper
298+ let to_integer = |x : Word | T :: from_limb_like ( Limb :: from ( x) , candidate. as_ref ( ) ) ;
299+
296300 // Find the base for the Lucas sequence.
297301 let ( p, abs_q, q_is_negative) = match base. generate ( candidate) {
298302 Ok ( pq) => pq,
@@ -328,7 +332,7 @@ pub fn lucas_test<T: Integer>(
328332 // it does not noticeably affect the performance.
329333 if abs_q != 1
330334 && gcd_vartime ( candidate. as_ref ( ) , abs_q) != 1
331- && candidate. as_ref ( ) > & T :: from ( abs_q)
335+ && candidate. as_ref ( ) > & to_integer ( abs_q)
332336 {
333337 return Primality :: Composite ;
334338 }
@@ -351,7 +355,7 @@ pub fn lucas_test<T: Integer>(
351355 let q = if q_is_one {
352356 one. clone ( )
353357 } else {
354- let abs_q = <T as Integer >:: Monty :: new ( T :: from ( abs_q) , params. clone ( ) ) ;
358+ let abs_q = <T as Integer >:: Monty :: new ( to_integer ( abs_q) , params. clone ( ) ) ;
355359 if q_is_negative {
356360 -abs_q
357361 } else {
@@ -364,7 +368,7 @@ pub fn lucas_test<T: Integer>(
364368 let p = if p_is_one {
365369 one. clone ( )
366370 } else {
367- <T as Integer >:: Monty :: new ( T :: from ( p) , params. clone ( ) )
371+ <T as Integer >:: Monty :: new ( to_integer ( p) , params. clone ( ) )
368372 } ;
369373
370374 // Compute d-th element of Lucas sequence (U_d(P, Q), V_d(P, Q)), where:
@@ -387,7 +391,7 @@ pub fn lucas_test<T: Integer>(
387391 let mut qk = one. clone ( ) ; // keeps Q^k
388392
389393 // D in Montgomery representation - note that it can be negative.
390- let abs_d = <T as Integer >:: Monty :: new ( T :: from ( abs_d) , params) ;
394+ let abs_d = <T as Integer >:: Monty :: new ( to_integer ( abs_d) , params) ;
391395 let d_m = if d_is_negative { -abs_d } else { abs_d } ;
392396
393397 for i in ( 0 ..d. bits_vartime ( ) ) . rev ( ) {
0 commit comments