''' This module provides a OneTimePad object that can be used to get a random string of bytes. If you trust python's os.urandom() function, you can use this module for cryptographically secure one time pads. If you provide a nonzero seed to the OneTimePad object, it will generate a repeatable sequence of one time pad strings. ------------------------------------------------------------- Copyright (C) 2005 Don Peterson This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ''' import os, random __version__ = "$Id: otp.py 1.3 2005/12/30 19:09:41 donp Exp $" class OneTimePad: '''Generate one time pads. If you initialize with seed != 0, the routine will use a repeatable random number generator. Otherwise, the os.urandom() generator is used (requires python 2.4). ''' def __init__(self, numbytes=16, seed = 0): self.numbytes = numbytes if seed: random.seed(seed) self.generator = self._getrandbytes else: self.generator = os.urandom def Get(self): # Return a one time pad in hex digits. str = "" for char in self.generator(self.numbytes): str += "%02X" % ord(char) return str def GetBinary(self): # Return a one time pad in binary. return self.generator(self.numbytes) def _getrandbytes(self, n): '''Return n random bytes using the random module's generator. ''' s = "" for i in xrange(n // 4): s += self._generate_string(random.getrandbits(32)) remainder = n % 4 if remainder: t = self._generate_string(random.getrandbits(32)) s += t[:remainder] return s def _generate_string(self, n): '''Generate a string from a four byte integer n. The string is the 4 bytes of the integer, each converted to a character. ''' str = "" str = str + chr((n & 0xFF000000) >> 24) str = str + chr((n & 0x00FF0000) >> 16) str = str + chr((n & 0x0000FF00) >> 8) str = str + chr((n & 0x000000FF) >> 0) return str if __name__ == "__main__": import sys numtimes = 1 if len(sys.argv) < 2: print "Usage: otp num_times [num_bytes [seed]]" sys.exit(1) numtimes = int(sys.argv[1]) size = 16 seed = 0 assert(numtimes > 0) if len(sys.argv) == 3: size = int(sys.argv[2]) if len(sys.argv) == 4: size = int(sys.argv[2]) seed = int(sys.argv[3]) o = OneTimePad(numbytes=size, seed=seed) for ix in xrange(numtimes): print o.Get()