Generate public/private keys, encrypt, decrypt, sign, verify












0












$begingroup$


My program generates public private keys, encrypts, decrypts, signs and verifies, while using AES for the bulk for speed. Many operations were chosen for speed. This works out of the box on 3.6+ . Windows idle env disallows it from working there, but Linux and mac is ideal. I do call gzip which I know I can replace with a module. I almost want to do my own Huffman coding for it but I don't know where to draw the line.



The RSA and DSA portions are written from number theory and don't use the modules, that was the point.



I'm using this as an educational tool force the unwilling to kinetically understand public and private key cryptography when passed on a USB etc. in a classroom setting. To see the clicks in peoples eyes when they understand signing or the like, that's why I'm sharing this code. I know there's much better ways to handle the data concatenation, but am happy that I'm processing the data at a binary level.



I love the prime number theorem and so should you.



#!/usr/bin/env python3
import os
import sys
import math
import re
import hashlib
import random
import base64
import string
import getpass
import multiprocessing as mp
from Crypto.Cipher import AES
from Crypto import Random
from Crypto.Protocol.KDF import PBKDF2

#Primality testing, extended greatest common divisor and least common multiple
def isprime(n):
if not n & 1: #check if first bit is 1
return False
for i in (3,5,7,11):
if divmod(n, i)[1] == 0:
return False
#Fermat
if (pow(2, n-1, n)) != 1:
return False
#MilRab, x**2 = 1 mod P - ERH
s = 0
d = n-1
while not d & 1:
d>>=1 #shifts binary rep of number right one place, same as dividing by 2^d
s+=1
assert(2**s * d == n-1) #Process to find s and d
def trial_composite(a):
if pow(a, d, n) == 1:
return False
for i in range(s):
if pow(a, 2**i * d, n) == n-1:
return False
return True
for i in range(100):#Number of Rabin Witness's
a = random.randrange(2, n-1)
if trial_composite(a):
return False
return True

def get1prime(keysize):
while True:
p = random.randrange(1<<(keysize), 1<<(keysize+2))
if isprime(p):
return p

def modInverse(a, m) : #Euclid's Extended Algorithm
m0 = m
y = 0
x = 1
while (a > 1) :
q = a // m
t = m
m = divmod(a,m)[1]
a = t
t = y
y = x - q * y
x = t
if (x < 0) :
x = x + m0
return x

def lcm(x, y):
lcm = (x*y)//math.gcd(x,y)
return lcm

##AES256CHUNK
def get_private_key(password):
salt = b"We will know, we must know"
kdf = PBKDF2(password, salt, 64, 1000)
key = kdf[:32]
return key

def encryptaes(raw, password):
private_key = password
raw = pad(raw)
iv = Random.new().read(AES.block_size)
cipher = AES.new(private_key, AES.MODE_CBC, iv)
return base64.b64encode(iv + cipher.encrypt(raw))

def decryptaes(enc, password):
private_key = password
enc = base64.b64decode(enc)
iv = enc[:16]
cipher = AES.new(private_key, AES.MODE_CBC, iv)
return unpad(cipher.decrypt(enc[16:]))

BLOCK_SIZE = 128 #Block is 128 no matter what,this is multiple of 16
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]

#RSA
#Unique and Arbitrary Pub E, a prime.
e = 66047 # because I can
#e = 65537

def encryptit(e, n, thestring):#for sigining pass d as e
rbinlist = ['{0:08b}'.format(x) for x in thestring]
catstring = ''
catstring += rbinlist[0].lstrip('0')
del rbinlist[0]
for i in rbinlist:
catstring += str(i)
puttynumber = int(catstring,2)
cypherstring = str(pow(puttynumber, e, n))
return cypherstring

def decryptit(d, n, cynum):#for signing pass e as d
decryptmsg = ''
n = int(n)
d = int(d)
puttynum = pow(int(cynum), d, n)
puttynum = '{0:08b}'.format(puttynum)
while True:
if len(puttynum)%8 == 0:
break
puttynum = '0{0}'.format(puttynum)
locs = re.findall('[01]{8}', puttynum)
for x in locs:
letter = chr(int(x,2))
decryptmsg += letter
return decryptmsg

#Begin User Flow
choice = input("""



Welcome to Dan's Cryptography Concept Program.
Generate/Encrypt/Decrypt/Sign
RSA++/DSA++/AES/OTP/Double DH key exch w SHA
Choose:
A: Generate New Public/Private Key Pair
B: Encrypt a File
C: Decrypt a File
=> """)

if choice == 'A' or choice == 'a':
try:
keysize = (int(input("Enter a keysize: "))>>1)
except ValueError as a:
print('Enter a numbernn')
sys.exit()
pubkeyname = input('Input desired public key name: ')
pkey = input('Input desired private key name: ')
pwkey = get_private_key(getpass.getpass(prompt='Password to protect your private key: ', stream=None))
print('Generating Keys...')
primes =
plist =
for i in range(mp.cpu_count()):
plist.append(keysize)
workpool = mp.Pool(processes=mp.cpu_count())
reslist = workpool.imap_unordered(get1prime, plist)
workpool.close()
for res in reslist:
if res:
primes.append(res)
workpool.terminate()
break
workpool.join()
#
workpool1 = mp.Pool(processes=mp.cpu_count())
reslist = workpool1.imap_unordered(get1prime, plist)
workpool1.close()
for res in reslist:
if res:
primes.append(res)
workpool1.terminate()
break
workpool1.join()
if primes[0] != primes[1]:
p, q = primes[0], primes[1]
else:
print('Supremely Unlucky Try Again')
exit()
n = p*q
cm = lcm(p-1, q-1)
print('Computing Private key ...')
d = modInverse(e, cm)
print('Private Key Size: {} bits'.format(keysize*2))
print('Functional Length of: {}'.format(len(bin((d)))))
keystring = encryptaes(str(d).encode('ascii', errors='ignore').decode('utf-8'),pwkey)
b64key = bytes.decode(base64.encodestring(bytes(str(hex(n)).encode())))
with open(pkey, 'w') as f1:
f1.write(str(n)+'n')
f1.write(bytes.decode(keystring))
with open(pubkeyname, 'w') as f2:
f2.write(b64key)
print('Complete - {} and {} generated'.format(pubkeyname,pkey))
print('e exponent: {}'.format(str(e)))
print("""
-----BEGIN PUBLIC KEY-----
{}-----END PUBLIC KEY-----
""".format(b64key))
b64privkey = b64key = bytes.decode(base64.encodestring(bytes(str(hex(d)).encode())))
print("""
-----BEGIN PRIVATE KEY-----
{}-----END PRIVATE KEY-----
""".format(b64privkey))

if choice == 'B' or choice == 'b':
lineoutholder =
pubkeyname = input('Enter PUBLIC key to encrypt with(recepient): ')
privkey = input('Enter your private KEY you wish to sign with(yours): ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private key: ', stream=None))
try:
with open(pubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
uhaeskey = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(32)])
n = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
workfile = input('Enter the file to ENCRYPT: ')
outfile = input('Enter filename to WRITE out: ')
sha256_hash = hashlib.sha256()
try:
with open(workfile, 'rb') as f2:
wholefile = f2.read()
with open(workfile, 'rb') as f2:#open again to clear memory
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
with open(privkey) as f3:
priv = f3.readlines()
except Exception as x:
print(x)
exit()
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
signature = pow(int(numhash), d, int(priv[0]))
aeskey = get_private_key(uhaeskey)
plaintext = base64.encodestring(wholefile)
cyphertext = bytes.decode(encryptaes(plaintext.decode('ascii'), aeskey))
shippedpw = encryptit(e, n, uhaeskey.encode())
concat = str(str(signature)+'CUTcutCUTcutCUT'+shippedpw+'CUTcutCUTcutCUT'+cyphertext)
with open(outfile, 'w') as f3:
f3.write(concat)
os.system('gzip -9 {0};mv {0}.gz {0}'.format(outfile))
print('Wrote to {} ...'.format(outfile))

if choice == 'C' or choice == 'c':
dspubkeyname = input('Enter the PUBLIC key to verify the signature with(sender): ')
try:
with open(dspubkeyname, 'r') as f1:
pubkey = f1.read()
except:
print('bad keyname')
exit()
nsig = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
privkey = input('YOUR private KEY filename to decrypt the data: ')
pwkey = get_private_key(getpass.getpass(prompt='Password for your private keyfile: ', stream=None))
workfile = input('Enter the file to DECRYPT: ')
outfile = input('Enter the filename to WRITE out: ')
print('DECRYPTING')
os.system('mv {0} {0}.gz;gzip -d {0}.gz'.format(workfile))
sha256_hash = hashlib.sha256()
try:
with open(workfile) as f1:
lineholder = f1.read().split('CUTcutCUTcutCUT')
signature, codedkey, cyphertext =lineholder[0], lineholder[1], lineholder[2]
except:
print('Bad file name or path')
exit()
try:
with open(privkey) as f2:
priv = f2.readlines()
except:
print('Bad private key location')
n = priv[0]
d = int(bytes.decode(decryptaes(priv[1], pwkey)))
sigdec = pow(int(signature), e, nsig)#Sig Verification step1
aeskey = decryptit(d, n, codedkey)
aeskey = get_private_key(aeskey)
decstr = bytes.decode(decryptaes(cyphertext, aeskey))
cleartext = base64.decodestring(bytes(decstr, 'ascii'))
with open(outfile, 'wb') as f1:
f1.write(cleartext)
with open(outfile, 'rb') as f2:
for byte_block in iter(lambda: f2.read(4096),b""):
sha256_hash.update(byte_block)
HASH = sha256_hash.hexdigest()
HASH = [ord(i) for i in HASH]
numhash = ''
for i in HASH:
numhash +=str(i)
if int(numhash) == int(sigdec):
print('Signature Verified')
else:
print('FAILURE, bad hash...')
print('Wrote out to {} '.format(outfile))









share|improve this question









New contributor




dhoyt902 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$

















    0












    $begingroup$


    My program generates public private keys, encrypts, decrypts, signs and verifies, while using AES for the bulk for speed. Many operations were chosen for speed. This works out of the box on 3.6+ . Windows idle env disallows it from working there, but Linux and mac is ideal. I do call gzip which I know I can replace with a module. I almost want to do my own Huffman coding for it but I don't know where to draw the line.



    The RSA and DSA portions are written from number theory and don't use the modules, that was the point.



    I'm using this as an educational tool force the unwilling to kinetically understand public and private key cryptography when passed on a USB etc. in a classroom setting. To see the clicks in peoples eyes when they understand signing or the like, that's why I'm sharing this code. I know there's much better ways to handle the data concatenation, but am happy that I'm processing the data at a binary level.



    I love the prime number theorem and so should you.



    #!/usr/bin/env python3
    import os
    import sys
    import math
    import re
    import hashlib
    import random
    import base64
    import string
    import getpass
    import multiprocessing as mp
    from Crypto.Cipher import AES
    from Crypto import Random
    from Crypto.Protocol.KDF import PBKDF2

    #Primality testing, extended greatest common divisor and least common multiple
    def isprime(n):
    if not n & 1: #check if first bit is 1
    return False
    for i in (3,5,7,11):
    if divmod(n, i)[1] == 0:
    return False
    #Fermat
    if (pow(2, n-1, n)) != 1:
    return False
    #MilRab, x**2 = 1 mod P - ERH
    s = 0
    d = n-1
    while not d & 1:
    d>>=1 #shifts binary rep of number right one place, same as dividing by 2^d
    s+=1
    assert(2**s * d == n-1) #Process to find s and d
    def trial_composite(a):
    if pow(a, d, n) == 1:
    return False
    for i in range(s):
    if pow(a, 2**i * d, n) == n-1:
    return False
    return True
    for i in range(100):#Number of Rabin Witness's
    a = random.randrange(2, n-1)
    if trial_composite(a):
    return False
    return True

    def get1prime(keysize):
    while True:
    p = random.randrange(1<<(keysize), 1<<(keysize+2))
    if isprime(p):
    return p

    def modInverse(a, m) : #Euclid's Extended Algorithm
    m0 = m
    y = 0
    x = 1
    while (a > 1) :
    q = a // m
    t = m
    m = divmod(a,m)[1]
    a = t
    t = y
    y = x - q * y
    x = t
    if (x < 0) :
    x = x + m0
    return x

    def lcm(x, y):
    lcm = (x*y)//math.gcd(x,y)
    return lcm

    ##AES256CHUNK
    def get_private_key(password):
    salt = b"We will know, we must know"
    kdf = PBKDF2(password, salt, 64, 1000)
    key = kdf[:32]
    return key

    def encryptaes(raw, password):
    private_key = password
    raw = pad(raw)
    iv = Random.new().read(AES.block_size)
    cipher = AES.new(private_key, AES.MODE_CBC, iv)
    return base64.b64encode(iv + cipher.encrypt(raw))

    def decryptaes(enc, password):
    private_key = password
    enc = base64.b64decode(enc)
    iv = enc[:16]
    cipher = AES.new(private_key, AES.MODE_CBC, iv)
    return unpad(cipher.decrypt(enc[16:]))

    BLOCK_SIZE = 128 #Block is 128 no matter what,this is multiple of 16
    pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
    unpad = lambda s: s[:-ord(s[len(s) - 1:])]

    #RSA
    #Unique and Arbitrary Pub E, a prime.
    e = 66047 # because I can
    #e = 65537

    def encryptit(e, n, thestring):#for sigining pass d as e
    rbinlist = ['{0:08b}'.format(x) for x in thestring]
    catstring = ''
    catstring += rbinlist[0].lstrip('0')
    del rbinlist[0]
    for i in rbinlist:
    catstring += str(i)
    puttynumber = int(catstring,2)
    cypherstring = str(pow(puttynumber, e, n))
    return cypherstring

    def decryptit(d, n, cynum):#for signing pass e as d
    decryptmsg = ''
    n = int(n)
    d = int(d)
    puttynum = pow(int(cynum), d, n)
    puttynum = '{0:08b}'.format(puttynum)
    while True:
    if len(puttynum)%8 == 0:
    break
    puttynum = '0{0}'.format(puttynum)
    locs = re.findall('[01]{8}', puttynum)
    for x in locs:
    letter = chr(int(x,2))
    decryptmsg += letter
    return decryptmsg

    #Begin User Flow
    choice = input("""



    Welcome to Dan's Cryptography Concept Program.
    Generate/Encrypt/Decrypt/Sign
    RSA++/DSA++/AES/OTP/Double DH key exch w SHA
    Choose:
    A: Generate New Public/Private Key Pair
    B: Encrypt a File
    C: Decrypt a File
    => """)

    if choice == 'A' or choice == 'a':
    try:
    keysize = (int(input("Enter a keysize: "))>>1)
    except ValueError as a:
    print('Enter a numbernn')
    sys.exit()
    pubkeyname = input('Input desired public key name: ')
    pkey = input('Input desired private key name: ')
    pwkey = get_private_key(getpass.getpass(prompt='Password to protect your private key: ', stream=None))
    print('Generating Keys...')
    primes =
    plist =
    for i in range(mp.cpu_count()):
    plist.append(keysize)
    workpool = mp.Pool(processes=mp.cpu_count())
    reslist = workpool.imap_unordered(get1prime, plist)
    workpool.close()
    for res in reslist:
    if res:
    primes.append(res)
    workpool.terminate()
    break
    workpool.join()
    #
    workpool1 = mp.Pool(processes=mp.cpu_count())
    reslist = workpool1.imap_unordered(get1prime, plist)
    workpool1.close()
    for res in reslist:
    if res:
    primes.append(res)
    workpool1.terminate()
    break
    workpool1.join()
    if primes[0] != primes[1]:
    p, q = primes[0], primes[1]
    else:
    print('Supremely Unlucky Try Again')
    exit()
    n = p*q
    cm = lcm(p-1, q-1)
    print('Computing Private key ...')
    d = modInverse(e, cm)
    print('Private Key Size: {} bits'.format(keysize*2))
    print('Functional Length of: {}'.format(len(bin((d)))))
    keystring = encryptaes(str(d).encode('ascii', errors='ignore').decode('utf-8'),pwkey)
    b64key = bytes.decode(base64.encodestring(bytes(str(hex(n)).encode())))
    with open(pkey, 'w') as f1:
    f1.write(str(n)+'n')
    f1.write(bytes.decode(keystring))
    with open(pubkeyname, 'w') as f2:
    f2.write(b64key)
    print('Complete - {} and {} generated'.format(pubkeyname,pkey))
    print('e exponent: {}'.format(str(e)))
    print("""
    -----BEGIN PUBLIC KEY-----
    {}-----END PUBLIC KEY-----
    """.format(b64key))
    b64privkey = b64key = bytes.decode(base64.encodestring(bytes(str(hex(d)).encode())))
    print("""
    -----BEGIN PRIVATE KEY-----
    {}-----END PRIVATE KEY-----
    """.format(b64privkey))

    if choice == 'B' or choice == 'b':
    lineoutholder =
    pubkeyname = input('Enter PUBLIC key to encrypt with(recepient): ')
    privkey = input('Enter your private KEY you wish to sign with(yours): ')
    pwkey = get_private_key(getpass.getpass(prompt='Password for your private key: ', stream=None))
    try:
    with open(pubkeyname, 'r') as f1:
    pubkey = f1.read()
    except:
    print('bad keyname')
    exit()
    uhaeskey = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(32)])
    n = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
    workfile = input('Enter the file to ENCRYPT: ')
    outfile = input('Enter filename to WRITE out: ')
    sha256_hash = hashlib.sha256()
    try:
    with open(workfile, 'rb') as f2:
    wholefile = f2.read()
    with open(workfile, 'rb') as f2:#open again to clear memory
    for byte_block in iter(lambda: f2.read(4096),b""):
    sha256_hash.update(byte_block)
    HASH = sha256_hash.hexdigest()
    with open(privkey) as f3:
    priv = f3.readlines()
    except Exception as x:
    print(x)
    exit()
    d = int(bytes.decode(decryptaes(priv[1], pwkey)))
    HASH = [ord(i) for i in HASH]
    numhash = ''
    for i in HASH:
    numhash +=str(i)
    signature = pow(int(numhash), d, int(priv[0]))
    aeskey = get_private_key(uhaeskey)
    plaintext = base64.encodestring(wholefile)
    cyphertext = bytes.decode(encryptaes(plaintext.decode('ascii'), aeskey))
    shippedpw = encryptit(e, n, uhaeskey.encode())
    concat = str(str(signature)+'CUTcutCUTcutCUT'+shippedpw+'CUTcutCUTcutCUT'+cyphertext)
    with open(outfile, 'w') as f3:
    f3.write(concat)
    os.system('gzip -9 {0};mv {0}.gz {0}'.format(outfile))
    print('Wrote to {} ...'.format(outfile))

    if choice == 'C' or choice == 'c':
    dspubkeyname = input('Enter the PUBLIC key to verify the signature with(sender): ')
    try:
    with open(dspubkeyname, 'r') as f1:
    pubkey = f1.read()
    except:
    print('bad keyname')
    exit()
    nsig = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
    privkey = input('YOUR private KEY filename to decrypt the data: ')
    pwkey = get_private_key(getpass.getpass(prompt='Password for your private keyfile: ', stream=None))
    workfile = input('Enter the file to DECRYPT: ')
    outfile = input('Enter the filename to WRITE out: ')
    print('DECRYPTING')
    os.system('mv {0} {0}.gz;gzip -d {0}.gz'.format(workfile))
    sha256_hash = hashlib.sha256()
    try:
    with open(workfile) as f1:
    lineholder = f1.read().split('CUTcutCUTcutCUT')
    signature, codedkey, cyphertext =lineholder[0], lineholder[1], lineholder[2]
    except:
    print('Bad file name or path')
    exit()
    try:
    with open(privkey) as f2:
    priv = f2.readlines()
    except:
    print('Bad private key location')
    n = priv[0]
    d = int(bytes.decode(decryptaes(priv[1], pwkey)))
    sigdec = pow(int(signature), e, nsig)#Sig Verification step1
    aeskey = decryptit(d, n, codedkey)
    aeskey = get_private_key(aeskey)
    decstr = bytes.decode(decryptaes(cyphertext, aeskey))
    cleartext = base64.decodestring(bytes(decstr, 'ascii'))
    with open(outfile, 'wb') as f1:
    f1.write(cleartext)
    with open(outfile, 'rb') as f2:
    for byte_block in iter(lambda: f2.read(4096),b""):
    sha256_hash.update(byte_block)
    HASH = sha256_hash.hexdigest()
    HASH = [ord(i) for i in HASH]
    numhash = ''
    for i in HASH:
    numhash +=str(i)
    if int(numhash) == int(sigdec):
    print('Signature Verified')
    else:
    print('FAILURE, bad hash...')
    print('Wrote out to {} '.format(outfile))









    share|improve this question









    New contributor




    dhoyt902 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.







    $endgroup$















      0












      0








      0





      $begingroup$


      My program generates public private keys, encrypts, decrypts, signs and verifies, while using AES for the bulk for speed. Many operations were chosen for speed. This works out of the box on 3.6+ . Windows idle env disallows it from working there, but Linux and mac is ideal. I do call gzip which I know I can replace with a module. I almost want to do my own Huffman coding for it but I don't know where to draw the line.



      The RSA and DSA portions are written from number theory and don't use the modules, that was the point.



      I'm using this as an educational tool force the unwilling to kinetically understand public and private key cryptography when passed on a USB etc. in a classroom setting. To see the clicks in peoples eyes when they understand signing or the like, that's why I'm sharing this code. I know there's much better ways to handle the data concatenation, but am happy that I'm processing the data at a binary level.



      I love the prime number theorem and so should you.



      #!/usr/bin/env python3
      import os
      import sys
      import math
      import re
      import hashlib
      import random
      import base64
      import string
      import getpass
      import multiprocessing as mp
      from Crypto.Cipher import AES
      from Crypto import Random
      from Crypto.Protocol.KDF import PBKDF2

      #Primality testing, extended greatest common divisor and least common multiple
      def isprime(n):
      if not n & 1: #check if first bit is 1
      return False
      for i in (3,5,7,11):
      if divmod(n, i)[1] == 0:
      return False
      #Fermat
      if (pow(2, n-1, n)) != 1:
      return False
      #MilRab, x**2 = 1 mod P - ERH
      s = 0
      d = n-1
      while not d & 1:
      d>>=1 #shifts binary rep of number right one place, same as dividing by 2^d
      s+=1
      assert(2**s * d == n-1) #Process to find s and d
      def trial_composite(a):
      if pow(a, d, n) == 1:
      return False
      for i in range(s):
      if pow(a, 2**i * d, n) == n-1:
      return False
      return True
      for i in range(100):#Number of Rabin Witness's
      a = random.randrange(2, n-1)
      if trial_composite(a):
      return False
      return True

      def get1prime(keysize):
      while True:
      p = random.randrange(1<<(keysize), 1<<(keysize+2))
      if isprime(p):
      return p

      def modInverse(a, m) : #Euclid's Extended Algorithm
      m0 = m
      y = 0
      x = 1
      while (a > 1) :
      q = a // m
      t = m
      m = divmod(a,m)[1]
      a = t
      t = y
      y = x - q * y
      x = t
      if (x < 0) :
      x = x + m0
      return x

      def lcm(x, y):
      lcm = (x*y)//math.gcd(x,y)
      return lcm

      ##AES256CHUNK
      def get_private_key(password):
      salt = b"We will know, we must know"
      kdf = PBKDF2(password, salt, 64, 1000)
      key = kdf[:32]
      return key

      def encryptaes(raw, password):
      private_key = password
      raw = pad(raw)
      iv = Random.new().read(AES.block_size)
      cipher = AES.new(private_key, AES.MODE_CBC, iv)
      return base64.b64encode(iv + cipher.encrypt(raw))

      def decryptaes(enc, password):
      private_key = password
      enc = base64.b64decode(enc)
      iv = enc[:16]
      cipher = AES.new(private_key, AES.MODE_CBC, iv)
      return unpad(cipher.decrypt(enc[16:]))

      BLOCK_SIZE = 128 #Block is 128 no matter what,this is multiple of 16
      pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
      unpad = lambda s: s[:-ord(s[len(s) - 1:])]

      #RSA
      #Unique and Arbitrary Pub E, a prime.
      e = 66047 # because I can
      #e = 65537

      def encryptit(e, n, thestring):#for sigining pass d as e
      rbinlist = ['{0:08b}'.format(x) for x in thestring]
      catstring = ''
      catstring += rbinlist[0].lstrip('0')
      del rbinlist[0]
      for i in rbinlist:
      catstring += str(i)
      puttynumber = int(catstring,2)
      cypherstring = str(pow(puttynumber, e, n))
      return cypherstring

      def decryptit(d, n, cynum):#for signing pass e as d
      decryptmsg = ''
      n = int(n)
      d = int(d)
      puttynum = pow(int(cynum), d, n)
      puttynum = '{0:08b}'.format(puttynum)
      while True:
      if len(puttynum)%8 == 0:
      break
      puttynum = '0{0}'.format(puttynum)
      locs = re.findall('[01]{8}', puttynum)
      for x in locs:
      letter = chr(int(x,2))
      decryptmsg += letter
      return decryptmsg

      #Begin User Flow
      choice = input("""



      Welcome to Dan's Cryptography Concept Program.
      Generate/Encrypt/Decrypt/Sign
      RSA++/DSA++/AES/OTP/Double DH key exch w SHA
      Choose:
      A: Generate New Public/Private Key Pair
      B: Encrypt a File
      C: Decrypt a File
      => """)

      if choice == 'A' or choice == 'a':
      try:
      keysize = (int(input("Enter a keysize: "))>>1)
      except ValueError as a:
      print('Enter a numbernn')
      sys.exit()
      pubkeyname = input('Input desired public key name: ')
      pkey = input('Input desired private key name: ')
      pwkey = get_private_key(getpass.getpass(prompt='Password to protect your private key: ', stream=None))
      print('Generating Keys...')
      primes =
      plist =
      for i in range(mp.cpu_count()):
      plist.append(keysize)
      workpool = mp.Pool(processes=mp.cpu_count())
      reslist = workpool.imap_unordered(get1prime, plist)
      workpool.close()
      for res in reslist:
      if res:
      primes.append(res)
      workpool.terminate()
      break
      workpool.join()
      #
      workpool1 = mp.Pool(processes=mp.cpu_count())
      reslist = workpool1.imap_unordered(get1prime, plist)
      workpool1.close()
      for res in reslist:
      if res:
      primes.append(res)
      workpool1.terminate()
      break
      workpool1.join()
      if primes[0] != primes[1]:
      p, q = primes[0], primes[1]
      else:
      print('Supremely Unlucky Try Again')
      exit()
      n = p*q
      cm = lcm(p-1, q-1)
      print('Computing Private key ...')
      d = modInverse(e, cm)
      print('Private Key Size: {} bits'.format(keysize*2))
      print('Functional Length of: {}'.format(len(bin((d)))))
      keystring = encryptaes(str(d).encode('ascii', errors='ignore').decode('utf-8'),pwkey)
      b64key = bytes.decode(base64.encodestring(bytes(str(hex(n)).encode())))
      with open(pkey, 'w') as f1:
      f1.write(str(n)+'n')
      f1.write(bytes.decode(keystring))
      with open(pubkeyname, 'w') as f2:
      f2.write(b64key)
      print('Complete - {} and {} generated'.format(pubkeyname,pkey))
      print('e exponent: {}'.format(str(e)))
      print("""
      -----BEGIN PUBLIC KEY-----
      {}-----END PUBLIC KEY-----
      """.format(b64key))
      b64privkey = b64key = bytes.decode(base64.encodestring(bytes(str(hex(d)).encode())))
      print("""
      -----BEGIN PRIVATE KEY-----
      {}-----END PRIVATE KEY-----
      """.format(b64privkey))

      if choice == 'B' or choice == 'b':
      lineoutholder =
      pubkeyname = input('Enter PUBLIC key to encrypt with(recepient): ')
      privkey = input('Enter your private KEY you wish to sign with(yours): ')
      pwkey = get_private_key(getpass.getpass(prompt='Password for your private key: ', stream=None))
      try:
      with open(pubkeyname, 'r') as f1:
      pubkey = f1.read()
      except:
      print('bad keyname')
      exit()
      uhaeskey = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(32)])
      n = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
      workfile = input('Enter the file to ENCRYPT: ')
      outfile = input('Enter filename to WRITE out: ')
      sha256_hash = hashlib.sha256()
      try:
      with open(workfile, 'rb') as f2:
      wholefile = f2.read()
      with open(workfile, 'rb') as f2:#open again to clear memory
      for byte_block in iter(lambda: f2.read(4096),b""):
      sha256_hash.update(byte_block)
      HASH = sha256_hash.hexdigest()
      with open(privkey) as f3:
      priv = f3.readlines()
      except Exception as x:
      print(x)
      exit()
      d = int(bytes.decode(decryptaes(priv[1], pwkey)))
      HASH = [ord(i) for i in HASH]
      numhash = ''
      for i in HASH:
      numhash +=str(i)
      signature = pow(int(numhash), d, int(priv[0]))
      aeskey = get_private_key(uhaeskey)
      plaintext = base64.encodestring(wholefile)
      cyphertext = bytes.decode(encryptaes(plaintext.decode('ascii'), aeskey))
      shippedpw = encryptit(e, n, uhaeskey.encode())
      concat = str(str(signature)+'CUTcutCUTcutCUT'+shippedpw+'CUTcutCUTcutCUT'+cyphertext)
      with open(outfile, 'w') as f3:
      f3.write(concat)
      os.system('gzip -9 {0};mv {0}.gz {0}'.format(outfile))
      print('Wrote to {} ...'.format(outfile))

      if choice == 'C' or choice == 'c':
      dspubkeyname = input('Enter the PUBLIC key to verify the signature with(sender): ')
      try:
      with open(dspubkeyname, 'r') as f1:
      pubkey = f1.read()
      except:
      print('bad keyname')
      exit()
      nsig = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
      privkey = input('YOUR private KEY filename to decrypt the data: ')
      pwkey = get_private_key(getpass.getpass(prompt='Password for your private keyfile: ', stream=None))
      workfile = input('Enter the file to DECRYPT: ')
      outfile = input('Enter the filename to WRITE out: ')
      print('DECRYPTING')
      os.system('mv {0} {0}.gz;gzip -d {0}.gz'.format(workfile))
      sha256_hash = hashlib.sha256()
      try:
      with open(workfile) as f1:
      lineholder = f1.read().split('CUTcutCUTcutCUT')
      signature, codedkey, cyphertext =lineholder[0], lineholder[1], lineholder[2]
      except:
      print('Bad file name or path')
      exit()
      try:
      with open(privkey) as f2:
      priv = f2.readlines()
      except:
      print('Bad private key location')
      n = priv[0]
      d = int(bytes.decode(decryptaes(priv[1], pwkey)))
      sigdec = pow(int(signature), e, nsig)#Sig Verification step1
      aeskey = decryptit(d, n, codedkey)
      aeskey = get_private_key(aeskey)
      decstr = bytes.decode(decryptaes(cyphertext, aeskey))
      cleartext = base64.decodestring(bytes(decstr, 'ascii'))
      with open(outfile, 'wb') as f1:
      f1.write(cleartext)
      with open(outfile, 'rb') as f2:
      for byte_block in iter(lambda: f2.read(4096),b""):
      sha256_hash.update(byte_block)
      HASH = sha256_hash.hexdigest()
      HASH = [ord(i) for i in HASH]
      numhash = ''
      for i in HASH:
      numhash +=str(i)
      if int(numhash) == int(sigdec):
      print('Signature Verified')
      else:
      print('FAILURE, bad hash...')
      print('Wrote out to {} '.format(outfile))









      share|improve this question









      New contributor




      dhoyt902 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.







      $endgroup$




      My program generates public private keys, encrypts, decrypts, signs and verifies, while using AES for the bulk for speed. Many operations were chosen for speed. This works out of the box on 3.6+ . Windows idle env disallows it from working there, but Linux and mac is ideal. I do call gzip which I know I can replace with a module. I almost want to do my own Huffman coding for it but I don't know where to draw the line.



      The RSA and DSA portions are written from number theory and don't use the modules, that was the point.



      I'm using this as an educational tool force the unwilling to kinetically understand public and private key cryptography when passed on a USB etc. in a classroom setting. To see the clicks in peoples eyes when they understand signing or the like, that's why I'm sharing this code. I know there's much better ways to handle the data concatenation, but am happy that I'm processing the data at a binary level.



      I love the prime number theorem and so should you.



      #!/usr/bin/env python3
      import os
      import sys
      import math
      import re
      import hashlib
      import random
      import base64
      import string
      import getpass
      import multiprocessing as mp
      from Crypto.Cipher import AES
      from Crypto import Random
      from Crypto.Protocol.KDF import PBKDF2

      #Primality testing, extended greatest common divisor and least common multiple
      def isprime(n):
      if not n & 1: #check if first bit is 1
      return False
      for i in (3,5,7,11):
      if divmod(n, i)[1] == 0:
      return False
      #Fermat
      if (pow(2, n-1, n)) != 1:
      return False
      #MilRab, x**2 = 1 mod P - ERH
      s = 0
      d = n-1
      while not d & 1:
      d>>=1 #shifts binary rep of number right one place, same as dividing by 2^d
      s+=1
      assert(2**s * d == n-1) #Process to find s and d
      def trial_composite(a):
      if pow(a, d, n) == 1:
      return False
      for i in range(s):
      if pow(a, 2**i * d, n) == n-1:
      return False
      return True
      for i in range(100):#Number of Rabin Witness's
      a = random.randrange(2, n-1)
      if trial_composite(a):
      return False
      return True

      def get1prime(keysize):
      while True:
      p = random.randrange(1<<(keysize), 1<<(keysize+2))
      if isprime(p):
      return p

      def modInverse(a, m) : #Euclid's Extended Algorithm
      m0 = m
      y = 0
      x = 1
      while (a > 1) :
      q = a // m
      t = m
      m = divmod(a,m)[1]
      a = t
      t = y
      y = x - q * y
      x = t
      if (x < 0) :
      x = x + m0
      return x

      def lcm(x, y):
      lcm = (x*y)//math.gcd(x,y)
      return lcm

      ##AES256CHUNK
      def get_private_key(password):
      salt = b"We will know, we must know"
      kdf = PBKDF2(password, salt, 64, 1000)
      key = kdf[:32]
      return key

      def encryptaes(raw, password):
      private_key = password
      raw = pad(raw)
      iv = Random.new().read(AES.block_size)
      cipher = AES.new(private_key, AES.MODE_CBC, iv)
      return base64.b64encode(iv + cipher.encrypt(raw))

      def decryptaes(enc, password):
      private_key = password
      enc = base64.b64decode(enc)
      iv = enc[:16]
      cipher = AES.new(private_key, AES.MODE_CBC, iv)
      return unpad(cipher.decrypt(enc[16:]))

      BLOCK_SIZE = 128 #Block is 128 no matter what,this is multiple of 16
      pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
      unpad = lambda s: s[:-ord(s[len(s) - 1:])]

      #RSA
      #Unique and Arbitrary Pub E, a prime.
      e = 66047 # because I can
      #e = 65537

      def encryptit(e, n, thestring):#for sigining pass d as e
      rbinlist = ['{0:08b}'.format(x) for x in thestring]
      catstring = ''
      catstring += rbinlist[0].lstrip('0')
      del rbinlist[0]
      for i in rbinlist:
      catstring += str(i)
      puttynumber = int(catstring,2)
      cypherstring = str(pow(puttynumber, e, n))
      return cypherstring

      def decryptit(d, n, cynum):#for signing pass e as d
      decryptmsg = ''
      n = int(n)
      d = int(d)
      puttynum = pow(int(cynum), d, n)
      puttynum = '{0:08b}'.format(puttynum)
      while True:
      if len(puttynum)%8 == 0:
      break
      puttynum = '0{0}'.format(puttynum)
      locs = re.findall('[01]{8}', puttynum)
      for x in locs:
      letter = chr(int(x,2))
      decryptmsg += letter
      return decryptmsg

      #Begin User Flow
      choice = input("""



      Welcome to Dan's Cryptography Concept Program.
      Generate/Encrypt/Decrypt/Sign
      RSA++/DSA++/AES/OTP/Double DH key exch w SHA
      Choose:
      A: Generate New Public/Private Key Pair
      B: Encrypt a File
      C: Decrypt a File
      => """)

      if choice == 'A' or choice == 'a':
      try:
      keysize = (int(input("Enter a keysize: "))>>1)
      except ValueError as a:
      print('Enter a numbernn')
      sys.exit()
      pubkeyname = input('Input desired public key name: ')
      pkey = input('Input desired private key name: ')
      pwkey = get_private_key(getpass.getpass(prompt='Password to protect your private key: ', stream=None))
      print('Generating Keys...')
      primes =
      plist =
      for i in range(mp.cpu_count()):
      plist.append(keysize)
      workpool = mp.Pool(processes=mp.cpu_count())
      reslist = workpool.imap_unordered(get1prime, plist)
      workpool.close()
      for res in reslist:
      if res:
      primes.append(res)
      workpool.terminate()
      break
      workpool.join()
      #
      workpool1 = mp.Pool(processes=mp.cpu_count())
      reslist = workpool1.imap_unordered(get1prime, plist)
      workpool1.close()
      for res in reslist:
      if res:
      primes.append(res)
      workpool1.terminate()
      break
      workpool1.join()
      if primes[0] != primes[1]:
      p, q = primes[0], primes[1]
      else:
      print('Supremely Unlucky Try Again')
      exit()
      n = p*q
      cm = lcm(p-1, q-1)
      print('Computing Private key ...')
      d = modInverse(e, cm)
      print('Private Key Size: {} bits'.format(keysize*2))
      print('Functional Length of: {}'.format(len(bin((d)))))
      keystring = encryptaes(str(d).encode('ascii', errors='ignore').decode('utf-8'),pwkey)
      b64key = bytes.decode(base64.encodestring(bytes(str(hex(n)).encode())))
      with open(pkey, 'w') as f1:
      f1.write(str(n)+'n')
      f1.write(bytes.decode(keystring))
      with open(pubkeyname, 'w') as f2:
      f2.write(b64key)
      print('Complete - {} and {} generated'.format(pubkeyname,pkey))
      print('e exponent: {}'.format(str(e)))
      print("""
      -----BEGIN PUBLIC KEY-----
      {}-----END PUBLIC KEY-----
      """.format(b64key))
      b64privkey = b64key = bytes.decode(base64.encodestring(bytes(str(hex(d)).encode())))
      print("""
      -----BEGIN PRIVATE KEY-----
      {}-----END PRIVATE KEY-----
      """.format(b64privkey))

      if choice == 'B' or choice == 'b':
      lineoutholder =
      pubkeyname = input('Enter PUBLIC key to encrypt with(recepient): ')
      privkey = input('Enter your private KEY you wish to sign with(yours): ')
      pwkey = get_private_key(getpass.getpass(prompt='Password for your private key: ', stream=None))
      try:
      with open(pubkeyname, 'r') as f1:
      pubkey = f1.read()
      except:
      print('bad keyname')
      exit()
      uhaeskey = ''.join([random.choice(string.ascii_letters + string.digits) for n in range(32)])
      n = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
      workfile = input('Enter the file to ENCRYPT: ')
      outfile = input('Enter filename to WRITE out: ')
      sha256_hash = hashlib.sha256()
      try:
      with open(workfile, 'rb') as f2:
      wholefile = f2.read()
      with open(workfile, 'rb') as f2:#open again to clear memory
      for byte_block in iter(lambda: f2.read(4096),b""):
      sha256_hash.update(byte_block)
      HASH = sha256_hash.hexdigest()
      with open(privkey) as f3:
      priv = f3.readlines()
      except Exception as x:
      print(x)
      exit()
      d = int(bytes.decode(decryptaes(priv[1], pwkey)))
      HASH = [ord(i) for i in HASH]
      numhash = ''
      for i in HASH:
      numhash +=str(i)
      signature = pow(int(numhash), d, int(priv[0]))
      aeskey = get_private_key(uhaeskey)
      plaintext = base64.encodestring(wholefile)
      cyphertext = bytes.decode(encryptaes(plaintext.decode('ascii'), aeskey))
      shippedpw = encryptit(e, n, uhaeskey.encode())
      concat = str(str(signature)+'CUTcutCUTcutCUT'+shippedpw+'CUTcutCUTcutCUT'+cyphertext)
      with open(outfile, 'w') as f3:
      f3.write(concat)
      os.system('gzip -9 {0};mv {0}.gz {0}'.format(outfile))
      print('Wrote to {} ...'.format(outfile))

      if choice == 'C' or choice == 'c':
      dspubkeyname = input('Enter the PUBLIC key to verify the signature with(sender): ')
      try:
      with open(dspubkeyname, 'r') as f1:
      pubkey = f1.read()
      except:
      print('bad keyname')
      exit()
      nsig = int(bytes.decode(base64.decodestring(bytes(pubkey.encode()))), 16)
      privkey = input('YOUR private KEY filename to decrypt the data: ')
      pwkey = get_private_key(getpass.getpass(prompt='Password for your private keyfile: ', stream=None))
      workfile = input('Enter the file to DECRYPT: ')
      outfile = input('Enter the filename to WRITE out: ')
      print('DECRYPTING')
      os.system('mv {0} {0}.gz;gzip -d {0}.gz'.format(workfile))
      sha256_hash = hashlib.sha256()
      try:
      with open(workfile) as f1:
      lineholder = f1.read().split('CUTcutCUTcutCUT')
      signature, codedkey, cyphertext =lineholder[0], lineholder[1], lineholder[2]
      except:
      print('Bad file name or path')
      exit()
      try:
      with open(privkey) as f2:
      priv = f2.readlines()
      except:
      print('Bad private key location')
      n = priv[0]
      d = int(bytes.decode(decryptaes(priv[1], pwkey)))
      sigdec = pow(int(signature), e, nsig)#Sig Verification step1
      aeskey = decryptit(d, n, codedkey)
      aeskey = get_private_key(aeskey)
      decstr = bytes.decode(decryptaes(cyphertext, aeskey))
      cleartext = base64.decodestring(bytes(decstr, 'ascii'))
      with open(outfile, 'wb') as f1:
      f1.write(cleartext)
      with open(outfile, 'rb') as f2:
      for byte_block in iter(lambda: f2.read(4096),b""):
      sha256_hash.update(byte_block)
      HASH = sha256_hash.hexdigest()
      HASH = [ord(i) for i in HASH]
      numhash = ''
      for i in HASH:
      numhash +=str(i)
      if int(numhash) == int(sigdec):
      print('Signature Verified')
      else:
      print('FAILURE, bad hash...')
      print('Wrote out to {} '.format(outfile))






      python cryptography






      share|improve this question









      New contributor




      dhoyt902 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question









      New contributor




      dhoyt902 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question








      edited 32 secs ago









      Jamal

      30.3k11119227




      30.3k11119227






      New contributor




      dhoyt902 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked 11 mins ago









      dhoyt902dhoyt902

      1




      1




      New contributor




      dhoyt902 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      dhoyt902 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      dhoyt902 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






















          0






          active

          oldest

          votes











          Your Answer





          StackExchange.ifUsing("editor", function () {
          return StackExchange.using("mathjaxEditing", function () {
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          });
          });
          }, "mathjax-editing");

          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "196"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });






          dhoyt902 is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f214375%2fgenerate-public-private-keys-encrypt-decrypt-sign-verify%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          dhoyt902 is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          dhoyt902 is a new contributor. Be nice, and check out our Code of Conduct.













          dhoyt902 is a new contributor. Be nice, and check out our Code of Conduct.












          dhoyt902 is a new contributor. Be nice, and check out our Code of Conduct.
















          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f214375%2fgenerate-public-private-keys-encrypt-decrypt-sign-verify%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Costa Masnaga

          Fotorealismo

          Sidney Franklin