woody-woodpacker/rsa64/primes.c

75 lines
1.2 KiB
C
Raw Normal View History

2024-04-09 14:55:13 +00:00
#include "rsa.h"
uint16_t get_random_bytes(int fd) {
uint16_t ret;
if (read(fd, &ret, sizeof(uint16_t)) == -1) {
2024-04-09 14:55:13 +00:00
exit(1);
}
return ret;
}
// n pow e mod m
uint64_t pow_mod(uint64_t n, uint64_t e, uint64_t m) {
2024-04-09 14:55:13 +00:00
uint64_t y = 1;
while (e > 1) {
if (e & 1) {
y = (y * n) % m;
2024-04-09 14:55:13 +00:00
}
n = (n * n) % m;
e = e >> 1;
2024-04-09 14:55:13 +00:00
}
return (n * y) % m;
2024-04-09 14:55:13 +00:00
}
bool is_prime(uint16_t n, size_t k_max, int fd) {
uint16_t a = get_random_bytes(fd);
uint16_t d = n - 1;
uint16_t s = 0;
2024-04-09 14:55:13 +00:00
while ((d & 1) == 0) {
s++;
d = d >> 1;
}
for (size_t k = 0; k < k_max; k++) {
a = 0;
2024-04-09 14:55:13 +00:00
while (a < 2 || a > (n - 2)) {
a = get_random_bytes(fd);
}
uint16_t x = pow_mod(a, d, n);
uint16_t y;
for (uint16_t i = 0; i < s; i++) {
2024-04-09 14:55:13 +00:00
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;
}
uint16_t generate_prime_fd(int fd) {
uint16_t n = get_random_bytes(fd);
n |= 1 << 15;
2024-04-09 14:55:13 +00:00
n |= 1;
2024-05-23 11:21:06 +00:00
while (!is_prime(n, 16, fd)) {
2024-04-09 14:55:13 +00:00
n = get_random_bytes(fd);
n |= 1 << 15;
2024-04-09 14:55:13 +00:00
n |= 1;
}
return n;
}
uint16_t generate_prime() {
2024-04-09 14:55:13 +00:00
int fd = open("/dev/urandom", O_RDONLY);
uint16_t n = generate_prime_fd(fd);
2024-04-09 14:55:13 +00:00
close(fd);
return n;
}