Skip to content
Snippets Groups Projects

python rsa stuff full

  • Clone with SSH
  • Clone with HTTPS
  • Embed
  • Share
    The snippet can be accessed without any authentication.
    Authored by Jakob Berger
    rsa.py 3.02 KiB
    import math
    from Crypto.Util import number
    from Crypto.PublicKey import RSA
    from time import time
    
    def extended_euclid(a, b):
        d = -1
        x = -1
        y = -1
        if b == 0:
            d = a
            x = 1
            y = 0
        else:
            x2 = 1
            x1 = 0
            y2 = 0
            y1 = 1
            while b > 0:
                q = abs(a//b)
                r = a - q * b
                x = x2 - q * x1
                y = y2 - q * y1
                # step two
                a = b
                b = r
                x2 = x1
                x1 = x
                y2 = y1
                y1 = y
        d = a
        x = x2
        y = y2
        return (d,x,y)
    
    # generate key components
    e = int(pow(2, 16) + 1)
    p = number.getStrongPrime(1024, e=e)
    q = number.getStrongPrime(1024, e=e)
    n = p * q
    phi = (p - 1) * (q - 1)
    d = number.inverse(e, phi)
    print('p', p, '\n q', q, '\n n', n, '\n phi', phi, '\n e', e, '\n d', d)
    
    # test it
    key = RSA.construct((n,e,d,p,q))
    random = number.getRandomInteger(64)
    print('Encrypting random number %i' % random)
    encrypted = key.encrypt(random, None)
    decrypted = key.decrypt(encrypted)
    print('Decrypted value %i' % decrypted)
    if decrypted != random:
        print('uh-oh')
    else:
        print('Decryption worked!')
    
    cp: int = int(pow(q, -1) % p)
    cq: int = int(pow(p, -1) % q)
    dp: int = d % (p - 1)
    dq: int = d % (q - 1)
    
    
    def decrypt_chinese_rest(x):
        xp: int = x % p
        xq: int = x % q
        # 2
        print('pow pow powpow', type(xq))
        yp: int = pow(xp,dp) % p
        yq: int = pow(xq,dq) % q
        # 3
        print('c done')
        return q * cp * yp + p * cq * yq % n
    
    
    def decrypt_naive(x):
        result: int = pow(x, d)
        print(type(result))
        result: int = result % n
        print(type(result))
        print('n done')
        return result
    
    
    def benchmark_chunky(x):
            results = []
            i = 0
            for c in bytearray(x):
                results.append(benchmark(i, c))
                i += 1
            elapsed_naive = 0.0
            elapsed_chinese = 0.0
            for result in results:
                elapsed_naive = elapsed_naive + result[0]
                elapsed_chinese = elapsed_chinese + result[1]
            print('----------------------------------------------------\n',
                  elapsed_naive, elapsed_chinese, elapsed_naive - elapsed_chinese, 1.0 - (elapsed_chinese / elapsed_naive))
    
    
    def benchmark(i, x):
        encrypt = key.encrypt(x, None)[0]
        start_chinese = time()
        result_chinese = decrypt_chinese_rest(encrypt)
        stop_chinese = time()
        elapsed_chinese = stop_chinese - start_chinese
    
        start_naive = time()
        result_naive = decrypt_naive(encrypt)
        stop_naive = time()
        elapsed_naive = stop_naive - start_naive
    
        if result_chinese != x or result_naive != x:
            raise AssertionError('decryption unsuccessful, naive %i, chinese: %i' % (result_naive ,result_chinese))
    
        print(i + 1, elapsed_naive, elapsed_chinese, elapsed_naive - elapsed_chinese, 1.0 - (elapsed_chinese/elapsed_naive))
        return elapsed_naive, elapsed_chinese
    
    # benchmark
    print('\t'.join(['#', 'naive duration', 'chinese duration', 'difference', '%']))
    for i in range(50):
        benchmark_chunky(number.getRandomInteger(2048))
    0% Loading or .
    You are about to add 0 people to the discussion. Proceed with caution.
    Finish editing this message first!
    Please register or to comment