Advertisement
Guest User

Buggy Baillie–PSW

a guest
Mar 9th, 2019
309
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 6.00 KB | None | 0 0
  1. package braille.psw.pkgfor.java;
  2.  
  3. import java.util.BitSet;
  4.  
  5. public class BraillePSWForJava {
  6.  
  7.     public static void main(String[] args) {
  8.         System.out.println(baillie_psw(1300843));
  9.        
  10.         System.out.println();
  11.        
  12.     }
  13.    
  14.    
  15.     static boolean baillie_psw(long candidate){
  16.     //Perform the Baillie-PSW probabilistic primality test on candidateS
  17.  
  18.     //Check divisibility by a short list of primes less than 50
  19.     for (long known_prime : new long []{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47}){
  20.         if (candidate == known_prime)
  21.             return true;
  22.         else if (candidate % known_prime == 0)
  23.             return false;
  24.     }
  25.  
  26.     //Now perform the Miller-Rabin primality test base 2
  27.     if (!millerRabinBase2(candidate))
  28.         return false;
  29.    
  30.     //Check that the number isn't a square number, as this will throw out
  31.     //calculating the correct value of D later on (and means we have a
  32.     //composite number)
  33.  
  34.     double sr = Math.sqrt(candidate);
  35.      
  36.         // If square root is an integer
  37.         boolean perfectSquare = ((sr - Math.floor(sr)) == 0);
  38.  
  39.   if (perfectSquare) return false;
  40.  
  41.     //Finally perform the Lucas primality test
  42.     long D = DChooser(candidate);
  43.     if (!lucas_pp(candidate, D, 1, (long)(1-D)/4))
  44.         return false;
  45.  
  46.     //You've probably got a prime!
  47.     return true;
  48.     }
  49.    
  50.     static long DChooser(long candidate){
  51.     //Choose a D value suitable for the Baillie-PSW test
  52.     long D = 5;
  53.     while (jacobiSymbol(D, candidate) != -1){
  54.         D += ( D > 0 ? 2 : -2);
  55.         D *= -1;
  56.     }
  57.  
  58.     return D;
  59. }
  60.    
  61.    
  62.     //Perform the Miller Rabin primality test base 2
  63.     static public boolean millerRabinBase2(long number){
  64.         long d = number - 1;
  65.         long s = 0;
  66.        
  67.         while(d % 2 == 0){
  68.             d = d >> 1;
  69.             s += 1;
  70.         }
  71.        
  72.         long x = powerModulus(2, d, number);
  73.        
  74.         if (x == 1 || x== number -1) return  true;
  75.        
  76.         for (int i = 0; i < s - 1; i++) {
  77.             x = powerModulus(x, 2, number);
  78.             if (x == 1) return  false;
  79.             else if (x == number -1) return true;
  80.         }
  81.         return false;
  82.     }
  83.    
  84.    
  85.    
  86.    
  87.     //Emulating Python's efficient pow(x,y,z)
  88.     static long powerModulus(long base, long exponent, long modulus)
  89.     {
  90.         // Initialize result
  91.         long res = 1;      
  92.          
  93.         // Update x if it is more  
  94.         // than or equal to p
  95.         base = base % modulus;  
  96.      
  97.         while (exponent > 0)
  98.         {
  99.             // If y is odd, multiply x
  100.             // with result
  101.             if((exponent & 1)==1)
  102.                 res = (res * base) % modulus;
  103.      
  104.             // y must be even now
  105.             // y = y / 2
  106.             exponent = exponent >> 1;  
  107.             base = (base * base) % modulus;  
  108.         }
  109.         return res;
  110.     }
  111.    
  112.    
  113.     //Calculate the Jacobi symbol (a/n)
  114.     static long jacobiSymbol(long a, long n){
  115.         if (n == 1) return 1;
  116.         else if (a == 0) return 0;
  117.         else if (a == 1) return 1;
  118.         else if (a == 2){
  119.             if (n % 8 >= 3 && n % 8 <= 5) return -1;
  120.             else if (n % 8 >= 1 && n % 8 <= 7) return 1;
  121.         }
  122.         else if (a < 0)
  123.             return (long) Math.pow(-1, ((n-1)/2)) * jacobiSymbol(-1 * a, n);
  124.  
  125.         if (a % 2 == 0)
  126.             return (long)jacobiSymbol(2, n) * jacobiSymbol((a / 2), n);
  127.         else if (a % n != a)
  128.             return jacobiSymbol(a % n, n);
  129.         else{
  130.             if (a % 4 == 3 && n % 4 == 3)
  131.                 return -1 * jacobiSymbol(n, a);
  132.             else
  133.                 return jacobiSymbol(n, a);
  134.             }
  135.     }
  136.    
  137.     public static BitSet convert(long value) {
  138.     BitSet bits = new BitSet();
  139.     int index = 0;
  140.     while (value != 0L) {
  141.       if (value % 2L != 0) {
  142.         bits.set(index);
  143.       }
  144.       ++index;
  145.       value = value >>> 1;
  146.     }
  147.     return bits;
  148.   }
  149.    
  150.     static long[] UVSubscript(long k, long n, long U, long V, long P, long Q, long D){
  151.         BitSet bitDigits = convert(k);
  152.         long subscript = 1;
  153.         for (int i = bitDigits.length()-2; i >= 0; i--) {
  154.             U = U*V % n;
  155.             V = (powerModulus(V, 2, n) - 2*powerModulus(Q, subscript, n)) % n;
  156.  
  157.             subscript *= 2;
  158.  
  159.             if (bitDigits.get(i)){
  160.                
  161.  
  162.                 if (((P * U + V) & 1) == 0){
  163.                     if (((D*U + P*V) & 1) == 0){
  164.                          
  165.                          U = (P*U + V) >> 1;
  166.                          V = (D*U + P*V) >> 1;
  167.                     }else{
  168.                          U = (P*U + V) >> 1;
  169.                          V = (D*U + P*V + n) >> 1;
  170.                     }
  171.                 } else if (((D * U + P * V) & 1) == 0){
  172.                     U = (P*U + V + n) >> 1;
  173.                     V = (D*U + P*V) >> 1;
  174.                 }else{
  175.                     U = (P*U + V + n) >> 1;
  176.                     V = (D*U + P*V + n) >> 1;
  177.                 }
  178.                
  179.                 subscript += 1;
  180.                 U = U % n;
  181.                 V = V % n;
  182.                
  183.             }
  184.         }
  185.         return new long[]{U, V};
  186.     }
  187.    
  188.     static boolean lucas_pp(long number, long D, long P, long Q){
  189.         long[] UV = UVSubscript(number+1, number, 1, P, P, Q, D);
  190.        
  191.         if (UV[0] != 0) return false;
  192.        
  193.         long d = number + 1;
  194.         long s = 0;
  195.        
  196.         while ((d & 1) == 0){
  197.             d = d >> 1;
  198.             s += 1;
  199.         }
  200.        
  201.         UV = UVSubscript(number + 1, number , 1, P, P, Q, D);
  202.        
  203.         if (UV[0] == 0) return true;
  204.        
  205.         for (int i = 0; i < s; i++) {
  206.             UV[0] = (UV[0]*UV[1]) % number;
  207.             UV[1] = (powerModulus(UV[1], 2, number) - 2*powerModulus(Q, d*((long)Math.pow(2, i)), number)) % number;
  208.             if (UV[1] == 0) return true;
  209.         }
  210.         return false;
  211.     }
  212.    
  213. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement