2

In the field of information security, some large prime numbers are often used. For example, the famous RSA algorithm must rely on two large prime numbers. Fortunately, there are a lot of prime numbers in natural numbers (it is very simple to prove that there are infinitely many prime numbers), and the density is not low, so it is not that difficult to find a prime number, but let you find one that can be used in the RSA algorithm Prime numbers are more difficult.

Violent Trial

Just imagine, if you were asked to find a prime number now, what would you do? I remember that after I just learned the basic grammar of the C language in college, there is an after-school question determine whether a number is a prime number . People with basic programming skills must be able to write the following code:

boolean checkPrime(int n) {
    for (int i = 2; i*i <= n; i++) {
        if (n%i == 0) {
            return false;
        }
    }
    return true;
}

The easiest way to determine prime numbers is to try to divide, which is the code above. Its principle is to go from 2 to the radical n to see if n can be divided by a certain number. If it can, then n is definitely not a prime number, otherwise it must be a prime number. This is indeed a simple, rude and correct method. The only problem is that it is too slow. The time complexity of determining a number is O(n). If you use this method to judge whether a number with hundreds of digits is a prime number, it may be calculated using the most advanced computer now, and it will take n years to figure it out.

Screening method

Of course, there is also a faster batch decision algorithm for prime number determination- Ehrlich filter O(n log log n) time complexity to find all prime numbers within n.

在这里插入图片描述
The principle is this, set up a marker array, first mark all multiples of 2 first, and then go back and find that 3 is not marked, then 3 must be a prime number, and then mark all multiples of 3 in the marker array , And then found that 4 has been marked to skip, to 5... until all the numbers are marked, then the remaining unmarked numbers are prime numbers, as shown in the figure above, the code is as follows:

int[] signs = new int[n+1];
void eratosthenes(int n) {
    for (int i = 2; i <= n; i++) {
        if (signs[i] == 0) {
            for (int j = i * i; j <= n; j += i) {
                signs[j] = 1;
            }
        }
    }
}

Although the Ehrlich screening method seems to be faster, he also has his own problems. First of all, he can only batch, when judging a single n, it is necessary to screen out all prime numbers smaller than n. Second, it also needs to rely on storage space to store the mark. So it still cannot be used in the judgment of very large prime numbers.

Is there a faster way to find a prime number? Since the Middle Ages, many mathematicians have been devoted to finding prime number formulas in biography. For example, Euler discovered in 1772 that $f(n) = n^2 + n + 41$ When n is less than 41, the value of f(n) is all prime numbers, although later mathematicians have discovered that it can generate larger prime numbers. Formulas, but the numbers that these formulas can generate are still very limited. In the Gaussian era, it was basically confirmed that simple prime number formulas did not exist. Therefore, Gauss believed that the determination of primality is a very difficult problem.

Fermat's Little Theorem

/img/bVcR1bN
However, things always turn for the better. Let us go back to 1636, the famous mathematician Fermat wrote such a formula in a letter.

If p is a prime number and a is not a multiple of p, then a^(p-1) ≡ 1(mod p)

It was later proved that the condition that a is not a multiple of p is not necessary. The meaning of this theorem is that as long as p is a prime number, then $(a^(p-1))mod p$ is always equal to 1. This is the famous Fermat's little theorem. Maybe you are already wondering whether you can use this theorem to determine prime numbers. Indeed, Fermat's little theorem is almost true , if a number p can make a^(p-1) ≡ 1(mod p), There is a high probability that p is a prime number, note that this is almost true.

public class PrimeNumCheck {
    public static boolean check(long a, long p) {
        long res = fastMod(a, p-1, p);
        return res == 1;
    }

    public static long fastMod(long x, long n, long m) {
        if (n == 1) {
            return x % m;
        }
        long tmp = fastMod(x, n>>1, m);
        if (n % 2 == 0) {
            return (tmp * tmp) % m;
        } else {
            return (tmp * tmp * x) % m;
        }
    }
    
    public static void main(String[] args) {
        System.out.println(check(2, 7));
    }
}

Using the above Java code, you can quickly and probabilistically determine whether a number is a prime number (the determination result is not 100% accurate), which also depends on the choice of a in the above code. The fast power algorithm is used above, which can reduce the time complexity of modulating a number to the nth power to O(logn). It seems that we can reduce the time complexity of determining prime numbers from O(n) to O(logn). This is a qualitative leap, from almost incalculable to computable. This paved the way for the application of large prime numbers. .

But don't worry, it has some minor flaws. I just said that Fermat's little theorem is almost true in reverse. I have been emphasizing that almost . Because some sum n can also make $a^(n-1) ≡ 1(mod n)$ true, these make the composite number of $a^(n-1) ≡ 1(mod n)$ be called based on a Pseudo prime numbers, for example, the first few 2-based pseudo prime numbers are 341, 561, 645... respectively. However, there are very few such pseudo primes. In fact, is less than 1/10^20 for a 512-bit number, and the pseudo prime number based on 2 is less than 1/10^20 . If it is a 1024-bit number, the probability of a pseudo prime is less than 1/10^41. How low is this probability? For example, the probability that you can randomly find a 512-bit pseudo-prime number based on 2 is less than the probability that you win the 5 million jackpot. So you are randomly looking for a prime number, and Fermat's little theorem based on 2 is sufficient.

Of course, if you have to pursue higher accuracy, you can still optimize. After all, the pseudo prime number based on 2 is not necessarily based on the pseudo prime number of other a, so we can change a few more a for Accuracy. But history tells us that there are always accidents. Some composite numbers can make Fermat's theorem hold for any a. These numbers are called Carmichael Numbers. The first few Carmichael numbers are 561 1105 1729... Another story about Carmichael numbers Up.

summary

The probabilistic solution of Fermat’s little theorem gives us a new way to solve the problem. It is like using Bloom filters. They are not 100% accurate, but they can be more accurate with controllable accuracy. Efficient solution. computer world can not only use space for time, but also accuracy for time.

For a magical mathematical theorem like Fermat’s theorem, I feel that this seems to be a small egg about numbers buried by God when he created something, and I also firmly believe that there are many such small colored eggs. Maybe that day we can find God hidden in The joke in Pi! !

Reference


xindoo
717 声望3k 粉丝