Miller-rabin primality test for orders of magnitude lower computational complexity
This commit is contained in:
parent
28209ca70e
commit
2c7904d2b3
3 changed files with 58 additions and 2 deletions
14
main.c
14
main.c
|
@ -41,6 +41,20 @@ int main() {
|
|||
|
||||
uint64_t n = p * q;
|
||||
|
||||
int before = SysTick->CNT;
|
||||
bool check_a = miller_rabin(p, 10);
|
||||
int miller = SysTick->CNT - before;
|
||||
|
||||
before = SysTick->CNT;
|
||||
bool check_b = is_prime(p);
|
||||
int isprime = SysTick->CNT - before;
|
||||
|
||||
printf("Is prime: %s %s\n", check_a ? "true" : "false",
|
||||
check_b ? "true" : "false");
|
||||
|
||||
printf("Miller took %d ticks\n", miller);
|
||||
printf("Is_prime took %d ticks\n", isprime);
|
||||
|
||||
// Make these work by patching printf
|
||||
printf("P: %u\n", (uint32_t)p);
|
||||
printf("Q: %u\n", (uint32_t)q);
|
||||
|
|
34
rsa.c
34
rsa.c
|
@ -54,7 +54,7 @@ uint64_t modexp(uint64_t a, uint64_t b, uint64_t m) {
|
|||
|
||||
uint64_t gen_prime(uint64_t min, uint64_t max) {
|
||||
uint64_t cand = 0;
|
||||
while (!is_prime(cand)) cand = prand_range(min, max);
|
||||
while (!miller_rabin(cand, 10)) cand = prand_range(min, max);
|
||||
|
||||
return cand;
|
||||
}
|
||||
|
@ -71,6 +71,38 @@ bool is_prime(int n) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool miller_rabin(int n, int k) {
|
||||
if (n < 2)
|
||||
return false;
|
||||
|
||||
int d = n - 1;
|
||||
int s = 0;
|
||||
|
||||
while (d % 2 == 0) {
|
||||
d /= 2;
|
||||
s++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < k; i++) {
|
||||
int a = prand_range(2, n - 2);
|
||||
int x = modexp(a, d, n);
|
||||
|
||||
if (x == 1 || x == n - 1)
|
||||
continue;
|
||||
|
||||
for (int r = 1; r < s; r++) {
|
||||
x = modexp(x, 2, n);
|
||||
if (x == n - 1)
|
||||
break;
|
||||
}
|
||||
|
||||
if (x != n - 1)
|
||||
return false; // Not prime
|
||||
}
|
||||
|
||||
return true; // Likely prime
|
||||
}
|
||||
|
||||
int mod_inverse(int e, int phi) {
|
||||
for (int d = 0; d < phi; d++) {
|
||||
if ((d * e) % phi == 1)
|
||||
|
|
12
rsa.h
12
rsa.h
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @brief Calculates greatest common divider of two integers using the euclidean
|
||||
|
@ -55,3 +55,13 @@ uint64_t gen_prime(uint64_t min, uint64_t max);
|
|||
* @return true if n is prime, false otherwise.
|
||||
*/
|
||||
bool is_prime(int n);
|
||||
|
||||
/**
|
||||
* @brief Performs the Miller-Rabin primality test to check if a number is
|
||||
* probably prime.
|
||||
*
|
||||
* @param n The number to test for primality.
|
||||
* @param k The number of rounds of testing to perform.
|
||||
* @return true if n is probably prime, false if n is composite.
|
||||
*/
|
||||
bool miller_rabin(int n, int k);
|
||||
|
|
Loading…
Add table
Reference in a new issue