# written by Stephen Vermeulen, http://vermeulen.ca/one-time-pad.html # placed in the public domain in 2006 # # make a one time pad out of the contents of a bunch of # files. Process is: # # 1. do a directory listing (of files greater than 8k) # 2. select 128 files at random from at least 256 files # 3. from each file select a 2k chunk of data, starting at # a random position in the file # 4. concat all the chunks of data into a list # 5. shuffle the list # 6. MD5 digest the list (initializing the digest with some # user entered random text), take 32 bytes off the list and # feed it to MD5, producing 16 bytes of output and save that # repeating until 128k of output is made import random import md5 import os import os.path import sys import binascii def dirlist(path, flist): d = os.listdir(path) for x in d: p = os.path.join(path, x) if os.path.isfile(p): if os.path.getsize(p) > 8196: flist.append(p) elif os.path.isdir(p): # recurse into this directory dirlist(p, flist) files = [] if len(sys.argv[1:]) > 0: for d in sys.argv[1:]: dirlist(d, files) else: print "Make a one time pad" print "Syntax is:" print " makeotp.py dir1 [dir2 ...]" print "where dir1 (etc.) are directories of files with at least 256 files" print "that are 8K or larger. If successful will create a file called 'otp.txt'" print "in the current directory" sys.exit(0) if len(files) < 256: print "Did not find enough suitable files, only found:", len(files) print "please run again with a different list of directories" sys.exit(0) salt = "" while len(salt) < 10: salt += raw_input( "Enter some random text and hit return (10 char min): " ) print "Total eligible files in the directories:", len(files) sfiles = random.sample(files, 128) data = [] for f in sfiles: n = os.path.getsize(f) - 2048 fin = open(f, "rb") fin.seek(random.randint(0, n)) d = fin.read(2048) fin.close() data = data + list(d) random.shuffle(data) m = md5.new() m.update(salt) fout = open("otp.txt", "w") i = 0 while i < len(data): for j in range(32): m.update(data[i + j]) z1 = m.digest() for j in range(32): m.update(data[i + j]) z2 = m.digest() fout.write("%04d: %s%s\n" % (i/64, binascii.hexlify(z1), binascii.hexlify(z2))) i += 64 fout.close() print "Wrote output to: otp.txt"