woody-woodpacker/rsa64/primes.c

79 lines
1.3 KiB
C

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