From 710593d77f59e5a66fdeed08a435491704288b86 Mon Sep 17 00:00:00 2001 From: SirGankalot <73303677+SirGankalot@users.noreply.github.com> Date: Wed, 19 Jun 2024 11:36:36 +0200 Subject: [PATCH] test new c rsa calc in ci --- service/Dockerfile | 8 ++++ service/src/call_c.py | 38 +++++++++++++++ service/src/key_gen.c | 89 +++++++++++++++++++++++++++++++++++ service/src/rsa_encryption.py | 32 ++----------- 4 files changed, 138 insertions(+), 29 deletions(-) create mode 100644 service/src/call_c.py create mode 100644 service/src/key_gen.c diff --git a/service/Dockerfile b/service/Dockerfile index b8b96b2..704db56 100644 --- a/service/Dockerfile +++ b/service/Dockerfile @@ -9,6 +9,14 @@ COPY entrypoint.sh / RUN chmod +x /entrypoint.sh RUN pip install -r src/requirements.txt +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + gcc \ + libc-dev \ + libgmp-dev && \ + rm -rf /var/lib/apt/lists/* + +RUN gcc -o src/key_gen src/key_gen.c -lgmp #CMD gunicorn --bind 0.0.0.0:9696 main:app diff --git a/service/src/call_c.py b/service/src/call_c.py new file mode 100644 index 0000000..0e7e40a --- /dev/null +++ b/service/src/call_c.py @@ -0,0 +1,38 @@ +import subprocess +import datetime +import logging +from gmpy2 import is_prime + +#done in dockerfile +def compile_c_program(): + result = subprocess.run(["gcc", "-o", "src/key_gen", "src/key_gen.c", "-lgmp"], capture_output=True, text=True) + if result.returncode == 0: + print("Compilation successful.") + else: + print(f"Compilation failed:\n{result.stderr}") + exit(1) + +def run_c_program(): + command = "./src/key_gen" + process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = process.communicate() + + if stderr: + print(f"Errors encountered:\n{stderr.decode('utf-8')}") + return None, None + + output = stdout.decode('utf-8').strip().split('\n') + output = list(output) + return output[0],output[1] + +def get_prime_from_c(): + while True: + p, q = run_c_program() + p = int(p) + q = int(q) + if is_prime(p) and is_prime(q) and p.bit_length() == 256 and q.bit_length() == 256: + return p,q + + + + diff --git a/service/src/key_gen.c b/service/src/key_gen.c new file mode 100644 index 0000000..71a3d1f --- /dev/null +++ b/service/src/key_gen.c @@ -0,0 +1,89 @@ +#include +#include +#include +#include +#include // Needed for getpid() function +#include // Needed for gettimeofday() function + +#define N 256 // Bit size for p and q + +void generate_random_prime(mpz_t prime, gmp_randstate_t state, mp_bitcnt_t bits) { + do { + mpz_urandomb(prime, state, bits); + mpz_setbit(prime, bits - 1); // Ensure most significant bit is set for correct bit size + mpz_nextprime(prime, prime); // Find the next prime number starting from prime + } while (mpz_sizeinbase(prime, 2) != bits); // Ensure exactly N bits +} + +int is_prime(mpz_t n, gmp_randstate_t state) { + return mpz_probab_prime_p(n, 50); // Adjust certainty level as needed +} + +void generate_primes(mpz_t p, mpz_t q, gmp_randstate_t state) { + mpz_t six; + mpz_init(six); + mpz_set_ui(six, 6); + + int found = 0; + + while (!found) { + // Generate random prime p + generate_random_prime(p, state, N); + + // Calculate q = p + 6 + mpz_add(q, p, six); + + // Check if q is prime and both p and q are exactly 256 bits + if (is_prime(q, state) && is_prime(p, state) && mpz_sizeinbase(p, 2) == N && mpz_sizeinbase(q, 2) == N) { + found = 1; + } + } + + mpz_clear(six); +} + +unsigned long long get_seed() { + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + + // Get current process ID + pid_t pid = getpid(); + + // Mix the time and process ID + unsigned long long seed = ts.tv_sec * 1000000000LL + ts.tv_nsec + pid; + + return seed; +} + +int main() { + // Initialize GMP random state + gmp_randstate_t state; + gmp_randinit_default(state); + + // Seed the random number generator with more randomness + unsigned long long seed = get_seed(); + gmp_randseed_ui(state, seed); + + mpz_t p, q; + mpz_inits(p, q, NULL); + + // Generate random primes + generate_primes(p, q, state); + + // Print the generated primes + gmp_printf("%Zd\n", p); + gmp_printf("%Zd\n", q); + + // Clear resources + mpz_clears(p, q, NULL); + gmp_randclear(state); + + return 0; +} + + + + + + + diff --git a/service/src/rsa_encryption.py b/service/src/rsa_encryption.py index b64dabb..262a2d1 100644 --- a/service/src/rsa_encryption.py +++ b/service/src/rsa_encryption.py @@ -9,8 +9,8 @@ import pickle import base64 -#change it back just for now bc main.py is not working localy from gmpy2 import is_prime +from . import call_c # the prime calculation is based on https://www.geeksforgeeks.org/how-to-generate-large-prime-numbers-for-rsa-algorithm/ # First 10000 prime numbers @@ -46,31 +46,6 @@ def getLowLevelPrime(n): break else: return randomnumber, randomnumber2 - - -def isMillerRabinPassed(mrc): - maxDivisionsByTwo = 0 - ec = mrc-1 - while ec % 2 == 0: - ec >>= 1 - maxDivisionsByTwo += 1 - assert(2**maxDivisionsByTwo * ec == mrc-1) - - def trialComposite(round_tester): - if pow(round_tester, ec, mrc) == 1: - return False - for i in range(maxDivisionsByTwo): - if pow(round_tester, 2**i * ec, mrc) == mrc-1: - return False - return True - - # Set number of trials here - numberOfRabinTrials = 20 - for i in range(numberOfRabinTrials): - round_tester = random.randrange(2, mrc) - if trialComposite(round_tester): - return False - return True def random_prime(): @@ -84,12 +59,11 @@ def test(p,q): q = p + 6 if test(p,q): if is_prime(p) and is_prime(q): return p,q - #if isMillerRabinPassed(p) and isMillerRabinPassed(q): return p,q - def get_keys(): - p,q = random_prime() + #p,q = random_prime() + p,q = call_c.get_prime_from_c() private_key, public_key = generate_key_pair(p,q) return private_key.save_pkcs1().decode(), public_key.save_pkcs1().decode()