#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; }