# Math56 HW7

# Problem 1: # Implement expmodk from math import * def expmodk(b,n,k): """expmodk(b,n,k): implements fast binary exponentiation (mod k)""" if n<0: print 'n cannot be negative'; return if n==0: return 1%k r = 1 t = 2**floor(log(n)/log(2)) while t >= 1: r = (r*r)%k if n>=t: r = (r*b)%k; n = n-t t = t/2 return r%k
# Driver print str(expmodk(5, 4, 1)) + ' should be 0' print str(expmodk(2, 0, 1)) + ' should be 0' print str(expmodk(15, 1, 14)) + ' should be 1' print str(expmodk(15, 22*10000, 23)) + ' should be 1'
 0 should be 0 0 should be 0 1 should be 1 1 should be 1
def BBPln2(d): s = 0 for k in range(1,d+1): s = (s + float(expmodk(2,d-k,k))/k)%1 for k in range(d+1,d+50): s = (s + float(1)/((2**(k-d))*k))%1 return s
def float_to_binary(num): exponent=0 shifted_num=num while shifted_num != int(shifted_num): shifted_num*=2 exponent+=1 if exponent==0: return '{0:0b}'.format(int(shifted_num)) binary='{0:0{1}b}'.format(int(shifted_num),exponent+1) integer_part=binary[:-exponent] fractional_part=binary[-exponent:].rstrip('0') return '{0}.{1}'.format(integer_part,fractional_part)
# Check for accuracy : !!Differ by 3 last digits!! print float_to_binary(BBPln2(150))[22:51] print float_to_binary(BBPln2(170))[2: 31] print float_to_binary(BBPln2(1000))[12:51] print float_to_binary(BBPln2(1010))[2:41]
 01100010110110001011011000100 01100010110110001011011000101 010101110001100000011111110100110010011 010101110001100000011111110100110010100
# 50 digits after 10^7th of ln(2) and runtime import time t = time.time() print float_to_binary(BBPln2(10000000))[2:51] print time.time() - t
 1011100101100110010101100011010110001111100011001 168.175928116
# Problem 2 # RSA Key Cracking key1=179769313486231590772930519078902473361797697894230657273430081157732675813959208849892482646646053861281898869742657270323229440686204767022930919271900527274583718133819901842696889033053089824214222518172084033941235127192805040873995986313952152670540722837219467732259679323955945799203544242564067805041 key2=179769313486231590772930519078902473361797697894230657273430081157732675813681747397617220208701538226633634342088990957126311087919206226056546553648096692857325734126303422223946090876411538096950017256926393251659877716424454414574669510488666999687401604264603649888486128037375020209461492622148898094967 key3=179769313486231590772930519078902473361797697894230657273430081157732675813232835210451626338042078231407123833450697627556701803561471712581415695451767043240238467665935308928763401765183776105486886424121053565413493300935564221054491393355732091184583718575151835074982914803430720900398472458467112424817
def mygcd(a,b): while b!=0: t=b; b=a%t; a = t return a
if mygcd(key1,key2) != 1: print 'key1 and key2 are cracked!' if mygcd(key1,key3) != 1: print 'key1 and key3 are cracked!' if mygcd(key2,key3) != 1: print 'key2 and key3 are cracked!'
 key2 and key3 are cracked!
from mpmath import * mp.dps = 310; def FermatFactor(n): x = ceil(sqrt(n)) xsqr = x*x y = sqrt(xsqr - n) while ((frac(y) != 0) and (x < (n+6)/9)): xsqr = xsqr + 2*x + 1 x = x + 1 y = sqrt(xsqr - n) if (frac(y) == 0): p = int(x-y) q = int(x+y) return str(n) + ' is factored into ' + str(p) + ' and ' + str(q) else: return str(n) + ' is prime!'
print FermatFactor(key1)
 17976931348623159077293051907890247336179769789423065727343008115773\ 26758139592088498924826466460538612818988697426572703232294406862047\ 67022930919271900527274583718133819901842696889033053089824214222518\ 17208403394123512719280504087399598631395215267054072283721946773225\ 9679323955945799203544242564067805041 is factored into 13407807929942597099574024998205846127479365820592393377723561443721\ 76403013922791746586958749790502760518527559600618425447017180223635\ 2957043296521397077 and 13407807929942597099574024998205846127479365820592393377723561443721\ 76403063871082160761072244071346914860538478701882040917331533626569\ 1156426568843119533
from operator import mul from sage.matrix.all import * def factorbaseexponents(fb,f): fbex = [0]*len(fb) # list of zeros for t in list(f): # loop over tuples in factors i = fb.index(t[0]) fbex[i] = t[1] return fbex def kraitchik(N,y,r): fb = prime_range(y) print 'Length of factorbase: ' + str(len(fb)) x = int(ceil(sqrt(N))) expmat = [] xlist = [] # find the matrix xsqr = x*x for t in range(1,r+1): d = xsqr % N f = factor(d) if f[-1][0]<= y: fbex = factorbaseexponents(fb,f) expmat.append(fbex) xlist.append(x) xsqr = xsqr + 2*x + 1 x = x+1 print 'Length of list of x: ' + str(len(xlist)) # get null basis A = matrix(GF(2), len(expmat), len(fb) , expmat) vecs = A.left_kernel().basis() print 'Size of null space: ' + str(len(vecs)) # check for valid u,v for vec in vecs: u = 1 vsqr = 1 for i in range(len(vec)): if vec[i] == 1: x = xlist[i] u = (u*x) mulv = reduce(mul, [a**b for a,b in zip(fb,expmat[i])],1) vsqr = vsqr*mulv v = int(sqrt(vsqr)) if ((((u+v)%N) != 0) and (((u-v)%N) != 0)): print gcd(u-v,N), gcd(u+v,N) return return 'Failed.'
kraitchik(1098413,25,200)
 Length of factorbase: 9 Length of list of x: 6 Size of null space: 2 563 1951
kraitchik(1125907426181141, 1000, 10000)
 Length of factorbase: 168 Length of list of x: 89 Size of null space: 4 1048583 1073741827
kraitchik(1180591624032052314157, 10000, 80000)
 Length of factorbase: 1229 Length of list of x: 603 Size of null space: 73 1073741827 1099511627791
kraitchik(18446744073709551617, 10000, 60000)
 Length of factorbase: 1229 Length of list of x: 600 Size of null space: 74 274177 67280421310721