def get_random_rsa(cls, bits=512, num_prime_checks=121): assert bits % 8 == 0 and bits >= 8 a = b = 0 while a==b: a, b = [get_random_prime(bits/2+1, final_num_checks=num_prime_checks) for _ in xrange(2)] modulus = a * b period = (a-1)*(b-1)*gcd(a-1, b-1) # anything^(1+period) == anything (mod modulus) exponent = period while gcd(exponent, period) != 1: exponent = get_random_number(16)+2**16 d, _ = solve_mod_problem(exponent, period, 1) return cls(exponent, modulus, d)
def compat_check(p1, p2): if (p1, p2) in compatCache: return compatCache[(p1, p2)] gcd1 = gcd(p1 - 1, p2) if gcd1 != 1: if (p1 - 4) % gcd1 != 0: compatCache[(p1, p2)] = False return False gcd2 = gcd(p2 - 1, p1) if gcd2 != 1: if (p2 - 4) % gcd2 != 0: compatCache[(p1, p2)] = False return False compatCache[(p1, p2)] = True return True
def make_keys(n_primes = 100, pq_bound = 100): ''' takes: int n returns: tuples_int pub, prv ''' n, p, q = 1, 1, 1 prms = primes.prime(n_primes) while math.log(n, 2) <= 1: while n < pq_bound: p, q = np.random.choice(prms, size = 2, replace = False) n = p * q print "Key bit length: {}".format(math.log(n, 2)) print "Generated by p: {} and q: {}".format(p, q) t = (p - 1) * (q - 1) # =: |{k | k < n && (k, n) == 0}| print "Euler's totient function of {}x{}={}: {}".format(p, q, n, t) e = t while primes.gcd(e, t) != 1 or e == 1: e = int(np.random.uniform(low = 1, high = t)) print "Public key: {}".format(e) d = primes.inv(e, t) print "Private key: {}".format(d) return (n, e), (n, d)
def compat_check(p1, p2): if (p1,p2) in compatCache: return compatCache[(p1,p2)] gcd1 = gcd(p1-1, p2) if gcd1 != 1: if (p1-4) % gcd1 != 0: compatCache[(p1,p2)] = False return False gcd2 = gcd(p2-1, p1) if gcd2 != 1: if (p2-4) % gcd2 != 0: compatCache[(p1,p2)] = False return False compatCache[(p1,p2)] = True return True
def generate_keys(p, q): # given two primes, calculate modulus M M = p * q # calculate phi(M) [(p - 1)(q - 1)] phi = M - p - q + 1 # obtain exponent k with gcd(k, phi(M)) == 1 k = 1 + (M - 1) // 2 k = k // primes.gcd(k, phi) # obtain multiplicative inverse of k, mod phi(M) l = mult_inv_mod_m(k, phi) return ((k, M), (l, M))
def computeBetter(a): valDict = { 0 : 2*a } for b in xrange(a, 0, -2*twoPowerList[a]): addToDict(valDict, gcd(a,b), 2) addToDict(valDict, 0, -2) addToDict(valDict, a, -1) sumz = (f(1) + f(0)) * valDict[0] * SIZE /2 del valDict[0] for c in xrange(1,SIZE+1): sumz += sum([f(pow(c,key, MOD-1)) * valDict[key] for key in valDict.keys()]) return sumz
def computeBetter(a): valDict = {0: 2 * a} for b in xrange(a, 0, -2 * twoPowerList[a]): addToDict(valDict, gcd(a, b), 2) addToDict(valDict, 0, -2) addToDict(valDict, a, -1) sumz = (f(1) + f(0)) * valDict[0] * SIZE / 2 del valDict[0] for c in xrange(1, SIZE + 1): sumz += sum( [f(pow(c, key, MOD - 1)) * valDict[key] for key in valDict.keys()]) return sumz
def answer(): numerator = denominator = 1 for i in range(10, 100): if not i % 10: continue for j in range(i+1, 100): if not j % 10: continue k, l = str(i), str(j) if(k.find(l[0]) >= 0): k, l = float(k[(k.find(l[0])+1)%2]), float(l[1]) elif(k.find(l[1]) >= 0): k, l = float(k[(k.find(l[1])+1)%2]), float(l[0]) else: continue if(i / j == k / l): numerator *= k denominator *= l return denominator / gcd(numerator, denominator)
totientVals = get_totient(int(math.sqrt(LIM) + 10)) # naive method. Not bad, .04737 seconds for 10^6 count = 0 for m in xrange(2,int(math.sqrt(LIM))+1): if m**2 > LIM: break # \/ this part is the slowest. if m**2 + (m-1)**2 > LIM: nRange = xrange(1,m,2) if m%2 == 0 else xrange(2,m,2) for n in nRange: if m**2 + n**2 > LIM: break if gcd(m,n) != 1: continue count += 1 elif m % 2 == 1: count += totientVals[m] / 2 else: count += totientVals[m] print "Answer:", count print "Time taken:", time.time() - START """ Time taken: 0.120429039001 # time for 10^7
def compute(a, b, c): if (a - b) % (2 * twoPowerList[b]) == 0: return pow(c, gcd(a, b), MOD - 1) return c % 2
def compute(a,b,c): if (a-b) % (2 * twoPowerList[b]) == 0: return pow(c, gcd(a,b), MOD-1) return c % 2
def gcd3(a,b,c): return gcd(gcd(a,b),c)
import time from fractions import Fraction from primes import gcd START = time.time() LIMIT = 10**4 count = 0 for denominator in xrange(1, LIMIT): numer_range = xrange(1, denominator / 100) if denominator % 2 == 1 else xrange( 1, denominator / 100, 2) for numerator in numer_range: if gcd(numerator, denominator) != 1: continue if gcd(numerator - 1, denominator) != 1 and gcd( numerator + 1, denominator) != 1: count += 1 #print Fraction(numerator, denominator) print count print "Time Taken:", time.time() - START """ i want to get the set of all numer, denom where: numer < denom / 100 gcd(numer, denom) = 1 gcd(numer-1, denom) != 1 gcd(numer+1, denom) != 1 how the hell do I get the overlap of the two groups of:
count) insertIntoDict(countDict, (iteration + 1, orderSide3 + 1, orderTriangle + 1, orderSide3, orderSide3), count) gcdDict = dict() count = -6 # ignore the case where size = 2 for order in xrange(2, SIZE + 1): for key in filter((lambda key: key[0] == order - 1), countDict.keys()): appendEntry(key) val1 = sum(countDict[key] for key in filter(( lambda key: key[0] == order and key[1] == 1), countDict.keys())) val3 = sum(countDict[key] for key in filter(( lambda key: key[0] == order and key[1] == 3), countDict.keys())) count += gcd(val1, val3) if gcd(val1, val3) > 30: print order, gcd(val1, val3), time.time() - START print count print "Time Taken:", time.time() - START for value in sorted(set(gcdDict.values())): if not m_r(value / 6): continue prime = value / 6 minKey = min(filter(lambda x: gcdDict[x] == value, gcdDict.keys())) print prime, '\t', \ minKey, '\t', \ modNum[prime], '\t', \ (minKey - modNum[prime]) / (prime -1.)
import time from primes import get_totient, gcd, crt START = time.time() lower_bound = 10**6 upper_bound = lower_bound + 5000 answer = 0 totients = get_totient(upper_bound) for n in xrange(lower_bound, upper_bound): for m in xrange(lower_bound, n): gcdVal = gcd(m,n) if gcdVal == 1: number = crt([n,m], [totients[n], totients[m]]) % (n * m) answer += number else: # if the two totients aren't equal mod the gcd, continue if totients[n] % gcdVal != totients[m] % gcdVal: continue values = [ (totients[n] / gcdVal), totients[m] / gcdVal ] number = crt([n/ gcdVal, m / gcdVal], values) * gcdVal + totients[n] % gcdVal answer += number print answer print "Time Taken:", time.time() - START """ Congratulations, the answer you gave to problem 531 is correct.
import time from primes import gcd START = time.time() SIZE = 1000 sumz = 0 for i in xrange(1,int(SIZE**.5)+1): sumz += i for j in xrange(i+1, SIZE/i+1): sumz += gcd(i,j) * 2 print "Answer:", sumz print "Time Taken:", time.time() - START """ def f(n) = sum( gcd(n, d) for d in xrange(1,n+1)) f(p) = 2p - 1 if p is a prime f(pq) = (2p-1)(2q-1) if p,q are primes f(p^2) = p(3p-2) if p is a prime f(p^3) = p^2(4p-3) if p is a prime f(p^n) = p^(n-1) * ((n+1)p-n) f(nm) = f(n) * f(m) if gcd(n,m) = 1
def simplify(n, d): gcd = primes.gcd(n, d) return (n // gcd, d // gcd)
# RSA demo import primes import sys p = 3 # one prime number q = 19 # another prime n = p * q # the product of the primes phi = (p - 1) * (q - 1) # the totient # Try a sensible value for the encryption exponent e = 5 # Check to see that this is OK if primes.gcd(phi, e) != 1: print 'e = %i was not a good choice' % e exit(0) # Find the value of the decryption exponent d = primes.invmod(phi, e) # Check that this is OK - should not have to do this if d * e % phi != 1: print '(d*e) mod (phi) != 1 - something really wrong here!!!' sys.exit(0) # Print out the prime numbers, n, the totient and the encryption and decryption exponents print 'p = %i, q = %i, n = %i, phi = %i, e = %i, d = %i\n' % (p, q, n, phi, e, d) # Encryption and decryption using the pow function to carry out modulo exponentiation ptext = 53 # NOTE: 53 decimal is the decimal ASCII value for the CHARACTER 5 ctext = pow(ptext, e, n) # encrypt the integer 53 print 'The ciphertext of %i is %i' % (ptext, ctext)
import time from primes import gcd START = time.time() SIZE = 1000 sumz = 0 for i in xrange(1, int(SIZE**.5) + 1): sumz += i for j in xrange(i + 1, SIZE / i + 1): sumz += gcd(i, j) * 2 print "Answer:", sumz print "Time Taken:", time.time() - START """ def f(n) = sum( gcd(n, d) for d in xrange(1,n+1)) f(p) = 2p - 1 if p is a prime f(pq) = (2p-1)(2q-1) if p,q are primes f(p^2) = p(3p-2) if p is a prime f(p^3) = p^2(4p-3) if p is a prime f(p^n) = p^(n-1) * ((n+1)p-n) f(nm) = f(n) * f(m) if gcd(n,m) = 1 """
def cheat_crt(prime_list): prime_prod = reduce(lambda x,y: x*y, prime_list) prime_tot = lcm_list([x-1 for x in prime_list]) prime_prod /= gcd(prime_prod, prime_tot) return crt([prime_prod, prime_tot], [0, prime_tot - 3])
totientVals = get_totient(int(math.sqrt(LIM) + 10)) # naive method. Not bad, .04737 seconds for 10^6 count = 0 for m in xrange(2, int(math.sqrt(LIM)) + 1): if m**2 > LIM: break # \/ this part is the slowest. if m**2 + (m - 1)**2 > LIM: nRange = xrange(1, m, 2) if m % 2 == 0 else xrange(2, m, 2) for n in nRange: if m**2 + n**2 > LIM: break if gcd(m, n) != 1: continue count += 1 elif m % 2 == 1: count += totientVals[m] / 2 else: count += totientVals[m] print "Answer:", count print "Time taken:", time.time() - START """ Time taken: 0.120429039001 # time for 10^7 Time taken: 0.00853085517883 # time for 10^7 excluding the slowest part... 15x faster to exclude it... gg computing the numbers that don't let us go up to the limit for n are the slowest ones, by a huge factor.
def cheat_crt(prime_list): prime_prod = reduce(lambda x, y: x * y, prime_list) prime_tot = lcm_list([x - 1 for x in prime_list]) prime_prod /= gcd(prime_prod, prime_tot) return crt([prime_prod, prime_tot], [0, prime_tot - 3])
insertIntoDict(countDict, (iteration + 1, orderTriangle, orderSide1, orderSide2, orderTriangle + 1), count) insertIntoDict(countDict, (iteration + 1, orderTriangle, orderSide3, orderSide2, orderTriangle + 1), count) insertIntoDict(countDict, (iteration + 1, orderTriangle, orderSide1, orderSide3, orderTriangle + 1), count) insertIntoDict(countDict, (iteration + 1, orderSide1+1, orderTriangle+1, orderSide1, orderSide1), count) insertIntoDict(countDict, (iteration + 1, orderSide2+1, orderTriangle+1, orderSide2, orderSide2), count) insertIntoDict(countDict, (iteration + 1, orderSide3+1, orderTriangle+1, orderSide3, orderSide3), count) gcdDict = dict() count = -6 # ignore the case where size = 2 for order in xrange(2,SIZE+1): for key in filter((lambda key: key[0] == order-1), countDict.keys()): appendEntry(key) val1 = sum(countDict[key] for key in filter( (lambda key: key[0] == order and key[1] == 1), countDict.keys())) val3 = sum(countDict[key] for key in filter( (lambda key: key[0] == order and key[1] == 3), countDict.keys())) count += gcd(val1, val3) if gcd(val1, val3) > 30: print order, gcd(val1, val3), time.time() - START print count print "Time Taken:", time.time() - START for value in sorted(set(gcdDict.values())): if not m_r(value/6): continue prime = value / 6 minKey = min(filter(lambda x: gcdDict[x] == value, gcdDict.keys())) print prime, '\t', \ minKey, '\t', \ modNum[prime], '\t', \
import time from fractions import Fraction from primes import gcd START = time.time() LIMIT = 10**4 count = 0 for denominator in xrange(1, LIMIT): numer_range = xrange(1, denominator / 100) if denominator % 2 == 1 else xrange(1, denominator / 100, 2) for numerator in numer_range: if gcd(numerator, denominator) != 1: continue if gcd(numerator - 1, denominator) != 1 and gcd(numerator +1, denominator) != 1: count += 1 #print Fraction(numerator, denominator) print count print "Time Taken:", time.time() - START """ i want to get the set of all numer, denom where: numer < denom / 100 gcd(numer, denom) = 1 gcd(numer-1, denom) != 1 gcd(numer+1, denom) != 1 how the hell do I get the overlap of the two groups of:
# pick two primes, calculate modulus M # and phi(M) # IN PRACTICE, find primes between 10^N and 10^M P1 = 23 P2 = 91 M = P1*P2 x = P1-1 y = P2-1 print(P1, P2, x, y) PHI = M-P1-P2+1 # not (p1-1)*(p2-1) # obtain exponent k with gcd(k,phi(M))=1 k = 1 + (M-1)//2 k = k//primes.gcd(k, PHI) # PUBLIC KEY is (k,M) print("P1=", P1, "P2=", P2, "M=", M, "phi(M)=", PHI, "K=", k) plaintext = "Test message" digitext = [ord(x) for x in plaintext] ciphertext = [modular_power(x, k, M) for x in digitext] print(plaintext) print(digitext) print(ciphertext) # calculate decode key ans = primes.extended_gcd(k, PHI)