woody-woodpacker/rsa64/primes.c

78 lines
1.3 KiB
C

#include "rsa.h"
uint32_t get_random_bytes(int fd) {
uint32_t ret;
if (read(fd, &ret, sizeof(uint32_t)) == -1) {
exit(1);
}
return ret;
}
// nn pow e mod mm
uint32_t pow_mod(uint32_t nn, uint32_t e, uint32_t mm) {
uint64_t x = nn;
uint64_t m = mm;
uint64_t y = 1;
while (e > 1) {
if (e % 2) {
y *= x;
e -= 1;
y = y % m;
}
x *= x;
e /= 2;
x = x % m;
}
return (uint32_t)(x * y % m);
}
bool is_prime(uint32_t n, uint32_t k_max, int fd) {
uint32_t a = get_random_bytes(fd);
uint32_t d = n - 1;
uint32_t s = 0;
while ((d & 1) == 0) {
s++;
d = d >> 1;
}
for (uint32_t k = 0; k < k_max; k++) {
while (a < 2 || a > (n - 2)) {
a = get_random_bytes(fd);
}
uint32_t x = pow_mod(a, d, n);
uint32_t y;
for (uint32_t i = 0; i < s; i++) {
y = pow_mod(x, 2, n);
if (y == 1 && x != 1 && x != n - 1)
return false;
x = y;
}
if (y != 1) {
return false;
}
}
return true;
}
uint32_t generate_prime_fd(int fd) {
uint32_t n = get_random_bytes(fd);
n |= 1 << 31;
n |= 1;
while (n % 65537 == 0 || !is_prime(n, 128, fd)) {
n = get_random_bytes(fd);
n |= 1 << 31;
n |= 1;
}
return n;
}
uint32_t generate_prime() {
int fd = open("/dev/urandom", O_RDONLY);
uint32_t n = generate_prime_fd(fd);
close(fd);
return n;
}