def main(): #this is the number of trials that the fermat primality test will use on p and q k = 10 print('rsa implementation') #get our two primes p and q. we can use 'is_prime' as the condition function print('\nenter primes p and q') p = gcdbez.get_int_input('p: ', lambda p: is_prime(p, k), 'p must be prime') q = gcdbez.get_int_input('q: ', lambda q: is_prime(q, k), 'q must be prime') #this will be the 'public modulus' n = p * q #this is Euler's phi (totient) function for n phi_n = (p - 1) * (q - 1) print(f'\nn = {n}, phi(n) = {phi_n}') print('\nenter public exponent e') e = gcdbez.get_int_input('e: ', lambda e: gcdbez.gcd(e, phi_n) == 1, 'e must be coprime to phi(n)') #find f, the multiplicative inverse of e mod (phi(n)) #since gcd(e, phi(n)) = 1, e is a unit and so has a multiplicative inverse f, _ = lincon.four_pnt(e, 1, phi_n) print() x = gcdbez.get_int_input('number to encode: ') print(f'encoded: {fast_mod_exp(x, e, n)}') x = gcdbez.get_int_input('number to decode: ') print(f'decoded: {fast_mod_exp(x, f, n)}')
def main(): print('solve linear diophantine equations of the form:\n') print(' ax + by = c\n') print('by finding an integer solution (x, y)\n') #get a, b and c a = gcdbez.get_int_input('a: ') b = gcdbez.get_int_input('b: ') c = gcdbez.get_int_input('c: ') start = timeit.default_timer() #find the gcd of a and b and a u and v satisfying au + bv = d using Bezout's identity d, u, v = gcdbez.gcd_bez(a, b) #find a particular solution by multiplying each Bezout coefficient by c / d s.t ax0 + by0 = c x0 = c // d * u y0 = c // d * v end = timeit.default_timer() #output the solutions (if they exist) print('\nequation and solutions:\n') print(f' {a}x + {b}y = {c}\n') if c % d != 0: print(f"no integer solutions, because {d} doesn't divide {c}") else: print( f'x = {x0} - {b // d}n and y = {y0} + {a // d}n for any integer n') print(f'finished in {round(end - start, 4)}s (4d.p)')
def main(): print('solve a system of linear congruences of the form:\n') print(' (a_1)x := b_1 mod (n_1)') print(' ...') print(' (a_k)x := b_k mod (n_k)\n') print('where k is a positive integer\n') #how many congruences are there? #k = gcdbez.get_int_input('k: ', lambda x: x > 0, 'k must be positive') print('enter the constants in each congruence:') #how long did the program take (not including waiting for user input or outputting) total_time = 0 i = 0 cont_flag = True while cont_flag: a = gcdbez.get_int_input('\na: ') b = gcdbez.get_int_input('b: ') n = gcdbez.get_int_input('n: ', lambda x: x > 0, 'n must be positive') print(f'{a}x := {b} mod ({n})\n') start = timeit.default_timer() #need to solve/simplify each congruence so its in the form x := b mod (n) otherwise we can't use #the chinese remainder theorem b, n = lincon.four_pnt(a, b, n) #its possible that the given congruence has no solutions if b == None: print(f'the last congruence has no solutions') elif i != 0: #amend our current solution so that it satisfies the new congruence cur_soln = solve(cur_soln, (b, n)) print(f'x = {cur_soln[0]} + {cur_soln[1]}t for any integer t') else: #on the first iteration produce the current solution by just solving the first congruence cur_soln = (b, n) print(f'x = {cur_soln[0]} + {cur_soln[1]}t for any integer t') i += 1 end = timeit.default_timer() total_time += end - start cont_flag = False if input("'quit' to quit: ") == 'quit' else True print(f'finished in {round(total_time, 4)}s (4d.p)')
def main(): print('find the prime-power factorisation of n > 1\n') n = gcdbez.get_int_input('n: ', lambda x: x > 1, 'n must be greater than 1') ppf = prime_pow_fact(n) table(ppf)
if b != 0: m = gcdbez.gcd(a, b) a, b = a // m, b // m else: #if b is zero then the solution must also be zero return 0, n #if a is +- 1, we can 'read off' a solution if a == 1: return b % n, n elif a == -1: return -b % n, n #step 4: find a p s.t gcd(a, b + pn) > 1 p, _ = four_pnt(n % a, -b % a, a) b += p * n if __name__ == '__main__': print('solve linear congruences of the form:\n') print(' ax := b mod (n)\n') print('by finding a particular solution using the four-point algorithm\n') a = gcdbez.get_int_input('a: ') b = gcdbez.get_int_input('b: ') n = gcdbez.get_int_input('n: ', lambda x: x > 0, 'n must be positive') start = timeit.default_timer() x0, n = four_pnt(a, b, n) end = timeit.default_timer() if x0 != None: print(f'\nx = {x0} + {n}t for any integer t') else: print("\nno solutions as gcd(a, n) doesn't divide b") print(f'finished in {round(end - start, 4)}s (4d.p)')