diff --git a/rsa64/primes.c b/rsa64/primes.c index 6194b23..3a4a584 100644 --- a/rsa64/primes.c +++ b/rsa64/primes.c @@ -1,49 +1,47 @@ #include "rsa.h" -uint32_t get_random_bytes(int fd) { - uint32_t ret; - if (read(fd, &ret, sizeof(uint32_t)) == -1) { +uint16_t get_random_bytes(int fd) { + uint16_t ret; + if (read(fd, &ret, sizeof(uint16_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; +// 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 % 2) { - y *= x; - e -= 1; - y = y % m; + if (e & 1) { + y = (y * n) % m; } - x *= x; - e /= 2; - x = x % m; + n = (n * n) % m; + e = e >> 1; } - return (uint32_t)(x * y % m); + return (n * 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; +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 (uint32_t k = 0; k < k_max; k++) { + for (size_t k = 0; k < k_max; k++) { + a = 0; while (a < 2 || a > (n - 2)) { a = get_random_bytes(fd); + //a &= 0xFFFF; } - uint32_t x = pow_mod(a, d, n); - uint32_t y; - for (uint32_t i = 0; i < s; i++) { + 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; @@ -56,22 +54,25 @@ bool is_prime(uint32_t n, uint32_t k_max, int fd) { return true; } -uint32_t generate_prime_fd(int fd) { - uint32_t n = get_random_bytes(fd); - n |= 1 << 31; +uint16_t generate_prime_fd(int fd) { + uint16_t n = get_random_bytes(fd); + n |= 1 << 15; n |= 1; + //n &= 0xFFFF; - while (n % 65537 == 0 || !is_prime(n, 128, fd)) { + while (/*n % 3 == 0 ||*/ !is_prime(n, 16, fd)) { n = get_random_bytes(fd); - n |= 1 << 31; + n |= 1 << 15; n |= 1; + //n &= 0xFFFF; } return n; } -uint32_t generate_prime() { +uint16_t generate_prime() { int fd = open("/dev/urandom", O_RDONLY); - uint32_t n = generate_prime_fd(fd); + uint16_t n = generate_prime_fd(fd); close(fd); return n; } + diff --git a/rsa64/rsa.c b/rsa64/rsa.c index 2c4c85b..45ae45c 100644 --- a/rsa64/rsa.c +++ b/rsa64/rsa.c @@ -3,20 +3,73 @@ rsa_t rsa_init(size_t len, bigint_t *primes) { rsa_t rsa; - printf("Generating two primes of length %d bits\n", RSA_BLOCK_SIZE / 2); +// printf("Generating two primes of length %d bits\n", RSA_BLOCK_SIZE / 2); //printf("Generating p...\n"); rsa.p = bigint_prime(len / 2, primes); - printf("p = %lu\n", ((uint64_t)rsa.p.data[1] << 32) + (uint64_t)rsa.p.data[0]); +// printf("p = %lu\n", ((uint64_t)rsa.p.data[1] << 32) + (uint64_t)rsa.p.data[0]); //printf("p = %u\n", rsa.p.data[0]); //printf("Generating q...\n"); rsa.q = bigint_prime(len / 2, primes); - printf("q = %lu\n", ((uint64_t)rsa.q.data[1] << 32) + (uint64_t)rsa.q.data[0]); +// printf("q = %lu\n", ((uint64_t)rsa.q.data[1] << 32) + (uint64_t)rsa.q.data[0]); //printf("q = %u\n", rsa.q.data[0]); return rsa; } +int64_t euler(int64_t r0, int64_t r1) { + int64_t s0 = 1; + int64_t s1 = 0; + int64_t t0 = 0; + int64_t t1 = 1; + int64_t q0 = 0; + + //printf("" + //printf("|% 20d|% 20ld|% 20ld|% 20ld|\n", 0, r0, s0, t0); + //printf("|% 20d|% 20ld|% 20ld|% 20ld|\n", 0, r1, s1, t1); + + while (r1 != 0) { + q0 = r0 / r1; + int64_t tmp = r0 % r1; + r0 = r1; + r1 = tmp; + tmp = s0 - q0 * s1; + s0 = s1; + s1 = tmp; + tmp = t0 - q0 * t1; + t0 = t1; + t1 = tmp; + //printf("|% 20ld|% 20ld|% 20ld|% 20ld|\n", q0, r1, s1, t1); + } + return s0; +} + +int64_t euler2(int64_t r0, int64_t r1) { + int64_t s0 = 1; + int64_t s1 = 0; + int64_t t0 = 0; + int64_t t1 = 1; + int64_t q0 = 0; + + //printf("" + printf("|% 20d|% 20ld|% 20ld|% 20ld|\n", 0, r0, s0, t0); + printf("|% 20d|% 20ld|% 20ld|% 20ld|\n", 0, r1, s1, t1); + + while (r1 != 0) { + q0 = r0 / r1; + int64_t tmp = r0 % r1; + r0 = r1; + r1 = tmp; + tmp = s0 - q0 * s1; + s0 = s1; + s1 = tmp; + tmp = t0 - q0 * t1; + t0 = t1; + t1 = tmp; + printf("|% 20ld|% 20ld|% 20ld|% 20ld|\n", q0, r1, s1, t1); + } + return t0; +} rsa_t rsa_generate_keys(size_t block_size) { size_t len = block_size / sizeof(uint32_t) / 8; bigint_t *primes = (bigint_t *)protected_malloc(3245 * sizeof(bigint_t)); @@ -40,10 +93,100 @@ rsa_t rsa_generate_keys(size_t block_size) { bigint_destroy(rsa.p); bigint_destroy(rsa.q); - for (int i = 0; i < 100; i++) { - printf("%u\n", generate_prime()); + //int64_t p = 56843;//(uint64_t)generate_prime(); + //int64_t q = 61861;//(uint64_t)generate_prime(); + //int64_t p = 36671; + //int64_t q = 53939; + //int64_t p = 57313; + //int64_t q = 51329; + //int64_t p = 39901; + //int64_t q = 43391; + +// int fd2 = open("/dev/urandom", O_RDONLY); + for (int try = 0; try < 1000; try++) { + + if (try % 100 == 0) + printf("try: %d\n", try); + int64_t p = (uint64_t)generate_prime(); + int64_t q = (uint64_t)generate_prime(); + //p = 63761; + //q = 65003; + int64_t ln = (p - 1) * (q - 1); + int64_t e = 11317; + //e = 11; + + while (ln % e == 0 || p == q) { + p = generate_prime(); + q = generate_prime(); + ln = (p - 1) * (q - 1); } + if (q > p) { + uint64_t tmp = p; + p = q; + q = tmp; + } + int64_t n = p * q; + + int64_t r0 = e; + int64_t r1 = ln; + int64_t s0 = 1; + int64_t s1 = 0; + int64_t t0 = 0; + int64_t t1 = 1; + int64_t q0 = 0; + + while (r1 != 0) { + q0 = r0 / r1; + int64_t tmp = r0 % r1; + r0 = r1; + r1 = tmp; + tmp = s0 - q0 * s1; + s0 = s1; + s1 = tmp; + tmp = t0 - q0 * t1; + t0 = t1; + t1 = tmp; + } + + int64_t d = euler(e, ln) + ln; + if (d > n) { + d -= ln; + } + +/* printf("p: %ld\n", p); + printf("q: %ld\n", q); + printf("ln: %ld\n", ln); + printf("n: %ld\n", n); + printf("d: %ld\n", d); + printf("e: %ld\n", e); + printf("d * e %% ln = %ld\n", (d*e)%ln);*/ + for (uint64_t m = 0; m < 16384; m++) { + //uint64_t m = get_random_bytes(fd2); + uint64_t c = pow_mod(m, e, n); + uint64_t m2 = pow_mod(c, d, n); + if (m != m2) { + printf("ERROR try: %d\nround: n/a\nmsg: %ld\ncypher: %ld\ndecrypted: %ld\nd: %ld\ne: %ld\np: %lu\nq: %lu\nn: %lu\n", try, m, c, m2, d, e, p, q, n); + break; + } + } + //int64_t m = 42; + /* + for (int64_t m = 41; m < 43; m++) { + int64_t c = pow_mod(m, e, n); + int64_t m2 = pow_mod(c, d, n); + if (d < 0) { + int64_t c2 = euler(c, n); + printf("c2: %ld\n", c2); + printf("c2 * c %% n = %ld\n", ((c2 + n)*c)%n); + printf("c2 * c %% n = %ld\n", ((c2)*c)%n); + m2 = pow_mod(c2 + n, -d, n); + } + printf("message: %ld\n", m); + printf("cypher: %ld\n", c); + printf("decrypted: %ld\n", m2); + }*/ + } return rsa; } diff --git a/rsa64/rsa.h b/rsa64/rsa.h index bd58963..8c6b6f6 100644 --- a/rsa64/rsa.h +++ b/rsa64/rsa.h @@ -54,7 +54,9 @@ void array_bitwise_right_shift(uint32_t *a, size_t len); void array_bitwise_right_shift(uint32_t *a, size_t len); void array_decrement(uint32_t *a, size_t len); -uint32_t generate_prime(); +uint16_t generate_prime(); +uint64_t pow_mod(uint64_t nn, uint64_t e, uint64_t mm); +uint16_t get_random_bytes(int fd); #endif