Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from Cryptodome.Random import get_random_bytes
- from Cryptodome.Random.random import randint
- from Cryptodome.Cipher import AES
- from Cryptodome.Util.number import getPrime, inverse, GCD, isPrime
- from decimal import Decimal, localcontext
- from asn1 import Decoder, Numbers
- # Const variables
- CONST_MENU = "Enter the command number:\n" \
- "1 - Common module attack\n" \
- "2 - Wiener's attack\n" \
- "3 - Broadcast attack\n" \
- "4 - Generate good params\n" \
- "5 - Exit\n"
- e_A = 19
- d_A = 8951491488994130591450329621877650875590787614606970058937815143686053318358202107047972075855819632910118594186744692140167595039187521846226346403222614451356200574228642229153896172507224827541911642805183200622905104153808495003541756444423328630360444190985600803253244353807892361102380307011854208574819752139939496660951494871927984549980488625440286371167657743869518972841272343531521006291036125249846126524161290654060186880137271184621266305463220181450640510156096194546448369361561507085982360214103719262850464289998418518504867457526466141884978401820512842646609720322247902138580946552136781341219
- d_V = 49872187
- # Read file
- def read_file(filename):
- data = b''
- with open(filename, "rb") as enc:
- for line in enc:
- data += line
- f = Decoder()
- f.start(data)
- f.enter()
- f.enter()
- f.enter()
- value = f.read()
- value = f.read()
- f.enter()
- op = list()
- value = f.read()[1]
- op.append(value)
- value = f.read()[1]
- op.append(value)
- f.leave()
- f.enter()
- f.leave()
- f.enter()
- key = f.read()[1]
- op.append(key)
- f.leave()
- f.leave()
- f.leave()
- f.enter()
- value = f.read()[1]
- length = f.read()[1]
- f.leave()
- f.leave()
- cipher_text = f.read()[1]
- op.append(cipher_text)
- op.append(length)
- return op
- # Get user filename
- def get_filename():
- return input("Enter filename: ")
- # RSA key generation
- def generate_rsa_key(bitness=1024):
- # Generate p and q for n
- p, q = getPrime(bitness, randfunc=get_random_bytes), \
- getPrime(bitness, randfunc=get_random_bytes)
- # Const p and q
- p = 94286323768322764949153206183630282231345205081506763411203480306975515026046638864603826268429591768662290063119783708397368191842260297446140330636685809073715186176664956589509295328164296329117310868897816232456701710285529107339058532391287911593547489660021540237002327209538165993210690581259545410397
- q = 106108794307657365398267707732909976878093634069950792052198750672833579926019821503569440635598344141344867274167934010440371985708002129308319095670726805616787587451771217696125714150662739391434063603898060265054692803724491140655842502897874479001759762422144543530517299276847463882834353536426154569131
- n = p * q
- phi = (p - 1) * (q - 1)
- # Generate e
- e = -1
- for i in range(1, phi - 1):
- if GCD(i, phi) == 1:
- e = i
- break
- # Const e
- e = 65537
- # d = e^-1
- d = inverse(e, phi)
- # (n, e) and d - public and private
- return [n, e, d]
- # Common module attack
- def common_module_attack():
- rsa_key = generate_rsa_key(1024)
- # 1. N = 2^f * s
- N = rsa_key[1] * rsa_key[2] - 1
- f = 1
- while N % (2 ** f) == 0:
- f += 1
- f -= 1
- s = N // 2 ** f
- # 2. a, b
- a = randint(0, rsa_key[0] - 1)
- b = pow(a, s, rsa_key[0])
- # 3. l, t
- l = 0
- t = 0
- while True:
- deg = pow(2, l)
- res = pow(b, deg, rsa_key[0])
- if res == 1:
- deg = pow(2, l - 1)
- tmp = pow(b, deg, rsa_key[0])
- if tmp == -1:
- a = randint(0, rsa_key[0] - 1)
- b = pow(a, s, rsa_key[0])
- l = 0
- continue
- else:
- t = tmp
- break
- l += 1
- p = GCD(t + 1, rsa_key[0])
- q = GCD(t - 1, rsa_key[0])
- phi = (p - 1) * (q - 1)
- da = inverse(e_A, phi)
- if da == d_A:
- print("Common module attack is successful\n")
- # Wieners input params generation
- def generate_wiener_params(bitness = 64):
- while True:
- # p = getPrime(bitness, randfunc=get_random_bytes)
- # q = getPrime(bitness, randfunc=get_random_bytes)
- p = 15733439112036677461
- q = 11928399707412783767
- if (q < p) and (p < 2 * q):
- n = p * q
- phi = (p - 1) * (q - 1)
- e = 109410315299163392886979402045049646523
- if GCD(e, phi) != 1:
- continue
- d = inverse(e, phi)
- zn = (n ** (1 / 4)) / 3
- if d < int(zn):
- return [e, n]
- # Fracs generation
- def generate_fracs(params, frac):
- if params[0] == 0 or params[1] == 0:
- return True
- if params[0] == 1:
- frac.append(params[1])
- return True
- if params[1] == 1:
- frac.append(params[0])
- return True
- if params[0] >= params[1]:
- frac.append(params[0] // params[1])
- params.insert(0, params[0] % params[1])
- params.remove(params[1])
- else:
- frac.append(params[1] // params[0])
- params.insert(1, params[1] % params[0])
- params.remove(params[2])
- generate_fracs(params, frac)
- # Wiener's attack
- def wieners_attack():
- params = generate_wiener_params(64)
- nums = list([params[0], params[1]])
- frac = list()
- if params[0] < params[1]:
- frac.append(0)
- generate_fracs(nums, frac)
- P_2 = 1
- Q_2 = 0
- P_1 = 0
- Q_1 = 1
- m = randint(0, params[1] - 1)
- print("Message: {}".format(m))
- for i in range(1, len(frac)):
- Pi = frac[i] * P_1 + P_2
- Qi = frac[i] * Q_1 + Q_2
- nod = GCD(Pi, Qi)
- Pi = Pi // nod
- Qi = Qi // nod
- if pow(m, params[0] * Qi, params[1]) == m % params[1]:
- if Qi == d_V:
- print("Wiener's attack is successful")
- print("Secret param d was {}".format(Qi))
- break
- Q_2 = Q_1
- P_2 = P_1
- P_1 = Pi
- Q_1 = Qi
- #
- def find_key(c_arr, n_arr, e):
- M = list()
- mod = 1
- for i in range(0, len(n_arr)):
- mod *= n_arr[i]
- for i in range(0, len(n_arr)):
- M.append(mod // n_arr[i])
- x = 0
- for n_i, c_i, M_i in zip(n_arr, c_arr, M):
- x += c_i * inverse(M_i, n_i) * M_i
- x = x % mod
- deg = 1 / e
- with localcontext() as ctx:
- ctx.prec = 300
- m = int(round(Decimal(x)) ** round(Decimal(deg), 10))
- return m.to_bytes(32, "big")
- def data_decrypt(key, cipher_text, l):
- iv = 16 * b' '
- cipher = AES.new(key, AES.MODE_CBC, iv)
- plain_text = cipher.decrypt(cipher_text)
- plain_text = plain_text[0:l]
- return plain_text
- # Broadcast attack
- def broadcast_attack():
- # read multiple files
- n_arr = list()
- c_arr = list()
- temp = -1
- e = -1
- for i in range(1, 6):
- temp = read_file(str(i) + ".txt")
- print(str(i) + ".txt")
- n_arr.append(temp[0])
- c_arr.append(temp[2])
- e = temp[1]
- key = find_key(c_arr, n_arr, e)
- with open("attack.txt", "wb") as at:
- at.write(data_decrypt(key, temp[3], temp[4]))
- print("Broadcast attack was successful")
- # Good crypto params
- def generate_good_crypto_params(bitness=1024):
- while 1:
- p, q = getPrime(bitness, randfunc=get_random_bytes), getPrime(bitness, randfunc=get_random_bytes)
- # Complexity increase param
- # if isPrime((p - 1) // 2) == False or isPrime((q - 1) // 2) == False:
- # continue
- n, phi = p * q, (p - 1) * (q - 1)
- e = randint(3 * 10 ** 15, 10 ** 21)
- if GCD(phi, e) != 1:
- continue
- d = inverse(e, phi)
- with localcontext() as ctx:
- ctx.prec = 300
- zn = int((round(Decimal(n)) ** round(Decimal(0.25), 2)) / round(Decimal(3)))
- if d < int(zn):
- continue
- print("Good crypto params:\np = {}\nq = {}\ne = {}\nn = {}\n" . format(p, q, e, n))
- # main func
- def main():
- while 1:
- user_choice = int(input(CONST_MENU))
- if user_choice == 1:
- common_module_attack()
- break
- elif user_choice == 2:
- wieners_attack()
- break
- elif user_choice == 3:
- broadcast_attack()
- break
- elif user_choice == 4:
- generate_good_crypto_params(1024)
- break
- elif user_choice == 5:
- return
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement