home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2010 November / maximum-cd-2010-11.iso / DiscContents / calibre-0.7.13.msi / file_2256 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-08-06  |  11.5 KB  |  372 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. __revision__ = '$Id: randpool.py,v 1.14 2004/05/06 12:56:54 akuchling Exp $'
  5. import time
  6. import array
  7. import types
  8. import warnings
  9. import os.path as os
  10. from Crypto.Util.number import long_to_bytes
  11.  
  12. try:
  13.     import Crypto.Util.winrandom as winrandom
  14. except:
  15.     winrandom = None
  16.  
  17. STIRNUM = 3
  18.  
  19. class RandomPool:
  20.     
  21.     def __init__(self, numbytes = 160, cipher = None, hash = None):
  22.         if hash is None:
  23.             hash = SHA
  24.             import Crypto.Hash
  25.         
  26.         if cipher is not None:
  27.             warnings.warn("'cipher' parameter is no longer used")
  28.         
  29.         if isinstance(hash, types.StringType):
  30.             hash = __import__('Crypto.Hash.' + hash, None, None, [
  31.                 'new'])
  32.             warnings.warn("'hash' parameter should now be a hashing module")
  33.         
  34.         self.bytes = numbytes
  35.         self.bits = self.bytes * 8
  36.         self.entropy = 0
  37.         self._hash = hash
  38.         self._randpool = array.array('B', [
  39.             0] * self.bytes)
  40.         self._event1 = self._event2 = 0
  41.         self._addPos = 0
  42.         self._getPos = hash.digest_size
  43.         self._lastcounter = time.time()
  44.         self._RandomPool__counter = 0
  45.         self._measureTickSize()
  46.         self._randomize()
  47.  
  48.     
  49.     def _updateEntropyEstimate(self, nbits):
  50.         self.entropy += nbits
  51.         if self.entropy < 0:
  52.             self.entropy = 0
  53.         elif self.entropy > self.bits:
  54.             self.entropy = self.bits
  55.         
  56.  
  57.     
  58.     def _randomize(self, N = 0, devname = '/dev/urandom'):
  59.         data = ''
  60.         if N <= 0:
  61.             nbytes = int((self.bits - self.entropy) / 8 + 0.5)
  62.         else:
  63.             nbytes = int(N / 8 + 0.5)
  64.         if winrandom:
  65.             data = winrandom.new().get_bytes(nbytes)
  66.         elif os.path.exists(devname):
  67.             
  68.             try:
  69.                 f = open(devname)
  70.                 data = f.read(nbytes)
  71.                 f.close()
  72.             except IOError:
  73.                 (num, msg) = None
  74.                 if num != 2:
  75.                     raise IOError, (num, msg)
  76.                 num != 2
  77.             except:
  78.                 None<EXCEPTION MATCH>IOError
  79.             
  80.  
  81.         None<EXCEPTION MATCH>IOError
  82.         if data:
  83.             self._addBytes(data)
  84.             self._updateEntropyEstimate(8 * len(data))
  85.         
  86.         self.stir_n()
  87.  
  88.     
  89.     def randomize(self, N = 0):
  90.         return self._randomize(N)
  91.  
  92.     
  93.     def stir_n(self, N = STIRNUM):
  94.         for i in xrange(N):
  95.             self.stir()
  96.         
  97.  
  98.     
  99.     def stir(self, s = ''):
  100.         entropy = self.entropy
  101.         self.add_event()
  102.         for i in range(self.bytes / self._hash.digest_size):
  103.             h = self._hash.new(self._randpool)
  104.             h.update(str(self._RandomPool__counter) + str(i) + str(self._addPos) + s)
  105.             self._addBytes(h.digest())
  106.             self._RandomPool__counter = self._RandomPool__counter + 1 & 0xFFFFFFFFL
  107.         
  108.         self._addPos = 0
  109.         self._getPos = self._hash.digest_size
  110.         self.add_event()
  111.         self.entropy = entropy
  112.  
  113.     
  114.     def get_bytes(self, N):
  115.         s = ''
  116.         i = self._getPos
  117.         pool = self._randpool
  118.         h = self._hash.new()
  119.         dsize = self._hash.digest_size
  120.         num = N
  121.         while num > 0:
  122.             h.update(self._randpool[i:i + dsize])
  123.             s = s + h.digest()
  124.             num = num - dsize
  125.             i = (i + dsize) % self.bytes
  126.             if i < dsize:
  127.                 self.stir()
  128.                 i = self._getPos
  129.                 continue
  130.         self._getPos = i
  131.         self._updateEntropyEstimate(-8 * N)
  132.         return s[:N]
  133.  
  134.     
  135.     def add_event(self, s = ''):
  136.         event = time.time() * 1000
  137.         delta = self._noise()
  138.         s = s + long_to_bytes(event) + 4 * chr(170) + long_to_bytes(delta)
  139.         self._addBytes(s)
  140.         if event == self._event1 and event == self._event2:
  141.             bits = 0
  142.         else:
  143.             bits = 0
  144.             while delta:
  145.                 delta = delta >> 1
  146.                 bits = bits + 1
  147.             if bits > 8:
  148.                 bits = 8
  149.             
  150.         self._event1 = event
  151.         self._event2 = self._event1
  152.         self._updateEntropyEstimate(bits)
  153.         return bits
  154.  
  155.     
  156.     def _noise(self):
  157.         t = time.time()
  158.         delta = ((t - self._lastcounter) / self._ticksize) * 1e+06
  159.         self._lastcounter = t
  160.         self._addBytes(long_to_bytes(long(1000 * time.time())))
  161.         self._addBytes(long_to_bytes(long(1000 * time.clock())))
  162.         self._addBytes(long_to_bytes(long(1000 * time.time())))
  163.         self._addBytes(long_to_bytes(long(delta)))
  164.         delta = delta % 255
  165.         return int(delta)
  166.  
  167.     
  168.     def _measureTickSize(self):
  169.         interval = [
  170.             None] * 100
  171.         h = self._hash.new(`(id(self), id(interval))`)
  172.         t = time.time()
  173.         h.update(`t`)
  174.         i = 0
  175.         j = 0
  176.         while i < 100:
  177.             t2 = time.time()
  178.             h.update(`(i, j, t2)`)
  179.             j += 1
  180.             delta = int((t2 - t) * 1e+06)
  181.             if delta:
  182.                 interval[i] = delta
  183.                 i += 1
  184.                 t = t2
  185.                 continue
  186.         interval.sort()
  187.         self._ticksize = interval[len(interval) / 2]
  188.         h.update(`(interval, self._ticksize)`)
  189.         self.stir(h.digest())
  190.  
  191.     
  192.     def _addBytes(self, s):
  193.         i = self._addPos
  194.         pool = self._randpool
  195.         for j in range(0, len(s)):
  196.             pool[i] = pool[i] ^ ord(s[j])
  197.             i = (i + 1) % self.bytes
  198.         
  199.         self._addPos = i
  200.  
  201.     
  202.     def getBytes(self, N):
  203.         warnings.warn('getBytes() method replaced by get_bytes()', DeprecationWarning)
  204.         return self.get_bytes(N)
  205.  
  206.     
  207.     def addEvent(self, event, s = ''):
  208.         warnings.warn('addEvent() method replaced by add_event()', DeprecationWarning)
  209.         return self.add_event(s + str(event))
  210.  
  211.  
  212.  
  213. class PersistentRandomPool(RandomPool):
  214.     
  215.     def __init__(self, filename = None, *args, **kwargs):
  216.         RandomPool.__init__(self, *args, **kwargs)
  217.         self.filename = filename
  218.         if filename:
  219.             
  220.             try:
  221.                 f = open(filename, 'rb')
  222.                 self.add_event()
  223.                 data = f.read()
  224.                 self.add_event()
  225.                 self.stir(data)
  226.                 f.close()
  227.             except IOError:
  228.                 pass
  229.             except:
  230.                 None<EXCEPTION MATCH>IOError
  231.             
  232.  
  233.         None<EXCEPTION MATCH>IOError
  234.  
  235.     
  236.     def save(self):
  237.         if self.filename == '':
  238.             raise ValueError, 'No filename set for this object'
  239.         self.filename == ''
  240.         self.stir_n()
  241.         f = open(self.filename, 'wb')
  242.         self.add_event()
  243.         f.write(self._randpool.tostring())
  244.         f.close()
  245.         self.add_event()
  246.         self.stir()
  247.  
  248.  
  249. _kb = 0
  250. if not _kb:
  251.     
  252.     try:
  253.         import msvcrt
  254.         
  255.         class KeyboardEntry:
  256.             
  257.             def getch(self):
  258.                 c = msvcrt.getch()
  259.                 if c in ('\x00', '\xe0'):
  260.                     c += msvcrt.getch()
  261.                 
  262.                 return c
  263.  
  264.             
  265.             def close(self, delay = 0):
  266.                 if delay:
  267.                     time.sleep(delay)
  268.                     while msvcrt.kbhit():
  269.                         msvcrt.getch()
  270.                 
  271.  
  272.  
  273.         _kb = 1
  274.     except:
  275.         pass
  276.  
  277.  
  278. if not _kb:
  279.     
  280.     try:
  281.         import termios
  282.         
  283.         class KeyboardEntry:
  284.             
  285.             def __init__(self, fd = 0):
  286.                 self._fd = fd
  287.                 self._old = termios.tcgetattr(fd)
  288.                 new = termios.tcgetattr(fd)
  289.                 new[3] = new[3] & ~(termios.ICANON) & ~(termios.ECHO)
  290.                 termios.tcsetattr(fd, termios.TCSANOW, new)
  291.  
  292.             
  293.             def getch(self):
  294.                 termios.tcflush(0, termios.TCIFLUSH)
  295.                 return os.read(self._fd, 1)
  296.  
  297.             
  298.             def close(self, delay = 0):
  299.                 if delay:
  300.                     time.sleep(delay)
  301.                     termios.tcflush(self._fd, termios.TCIFLUSH)
  302.                 
  303.                 termios.tcsetattr(self._fd, termios.TCSAFLUSH, self._old)
  304.  
  305.  
  306.         _kb = 1
  307.     except:
  308.         pass
  309.  
  310.  
  311.  
  312. class KeyboardRandomPool(PersistentRandomPool):
  313.     
  314.     def __init__(self, *args, **kwargs):
  315.         PersistentRandomPool.__init__(self, *args, **kwargs)
  316.  
  317.     
  318.     def randomize(self, N = 0):
  319.         import os
  320.         import string
  321.         import time
  322.         if N <= 0:
  323.             bits = self.bits - self.entropy
  324.         else:
  325.             bits = N * 8
  326.         if bits == 0:
  327.             return None
  328.         print bits, 'bits of entropy are now required.  Please type on the keyboard'
  329.         print 'until enough randomness has been accumulated.'
  330.         kb = KeyboardEntry()
  331.         s = ''
  332.         hash = self._hash
  333.         e = 0
  334.         
  335.         try:
  336.             while e < bits:
  337.                 temp = str(bits - e).rjust(6)
  338.                 os.write(1, temp)
  339.                 s = s + kb.getch()
  340.                 e += self.add_event(s)
  341.                 os.write(1, 6 * chr(8))
  342.             self.add_event(s + hash.new(s).digest())
  343.         finally:
  344.             kb.close()
  345.  
  346.         print '\n\x07 Enough.  Please wait a moment.\n'
  347.         self.stir_n()
  348.         kb.close(4)
  349.  
  350.  
  351. if __name__ == '__main__':
  352.     pool = RandomPool()
  353.     print 'random pool entropy', pool.entropy, 'bits'
  354.     pool.add_event('something')
  355.     print `pool.get_bytes(100)`
  356.     import tempfile
  357.     import os
  358.     fname = tempfile.mktemp()
  359.     pool = KeyboardRandomPool(filename = fname)
  360.     print 'keyboard random pool entropy', pool.entropy, 'bits'
  361.     pool.randomize()
  362.     print 'keyboard random pool entropy', pool.entropy, 'bits'
  363.     pool.randomize(128)
  364.     pool.save()
  365.     saved = open(fname, 'rb').read()
  366.     print 'saved', `saved`
  367.     print 'pool ', `pool._randpool.tostring()`
  368.     newpool = PersistentRandomPool(fname)
  369.     print 'persistent random pool entropy', pool.entropy, 'bits'
  370.     os.remove(fname)
  371.  
  372.