78 lines
1.3 KiB
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;
|
||
|
}
|