ó
BwLc           @   s~   d  Z  d d l Td d l Z d d l m Z m Z m Z d d l m Z d d l	 m
 Z
 d d l Z d e f d     YZ d S(	   s   $Id$iĸĸĸĸ(   t   *N(   t
   ceil_shiftt
   exact_log2t	   exact_div(   t   Counter(   t   AESt   AESGeneratorc           B   sg   e  Z d  Z e j Z d Z d Z d e d Z d   Z d   Z	 d   Z
 d	   Z d
   Z d   Z RS(   s)  The Fortuna "generator"

    This is used internally by the Fortuna PRNG to generate arbitrary amounts
    of pseudorandom data from a smaller amount of seed data.

    The output is generated by running AES-256 in counter mode and re-keying
    after every mebibyte (2**16 blocks) of output.
    i    i   i   t    i   c         C   s­   t  j d |  j d d d d t  |  _ d  |  _ t |  j  |  _ d |  j >|  j k s_ t	  t
 |  j |  j  |  _ |  j |  j |  j k s t	  |  j |  j |  _ d  S(   Nt   nbitsi   t   initial_valuei    t   little_endiani   (   R   t   newt
   block_sizet   Truet   countert   Nonet   keyR   t   block_size_shiftt   AssertionErrorR   t   key_sizet   blocks_per_keyt   max_blocks_per_requestt   max_bytes_per_request(   t   self(    (    sJ   /usr/lib/python2.7/dist-packages/Crypto/Random/Fortuna/FortunaGenerator.pyt   __init__>   s    (	c         C   sq   |  j  d  k r" d |  j |  _  n  |  j t j |  j  |  j    |  j   t |  j   |  j k sm t	  d  S(   NR   (
   R   R   R   t   _set_keyt   SHAd256R   t   digestR   t   lenR   (   R   t   seed(    (    sJ   /usr/lib/python2.7/dist-packages/Crypto/Random/Fortuna/FortunaGenerator.pyt   reseedK   s
    #
c         C   s|   | d k s t   | d ?} | d @} g  } x* t |  D] } | j |  j d   q9 W| j |  j |   d j |  S(   Ni    i   i   t    i   iĸĸ i   (   R   t   xranget   appendt   _pseudo_random_datat   join(   R   t   bytest   num_full_blockst	   remaindert   retvalt   i(    (    sJ   /usr/lib/python2.7/dist-packages/Crypto/Random/Fortuna/FortunaGenerator.pyt   pseudo_random_dataR   s    

c         C   s.   | |  _  t j | t j d |  j |  _ d  S(   NR   (   R   R   R   t   MODE_CTRR   t   _cipher(   R   R   (    (    sJ   /usr/lib/python2.7/dist-packages/Crypto/Random/Fortuna/FortunaGenerator.pyR   _   s    	c         C   sĶ   d | k o |  j  k n s. t d   n  t | |  j  } |  j |  |  } |  j |  j |  j   t |  | k s t  t |  j  |  j	 k sĒ t  | S(   Ni    s6   You cannot ask for more than 1 MiB of data per request(
   R   R   R   R   t   _generate_blocksR   R   R   R   R   (   R   R$   t
   num_blocksR'   (    (    sJ   /usr/lib/python2.7/dist-packages/Crypto/Random/Fortuna/FortunaGenerator.pyR"   c   s    c         C   sū   |  j  d  k r t d   n  d | k o8 |  j k n sC t  g  } x4 t | d ? D]" } | j |  j j |  j   qZ W| d @|  j	 >} | j |  j j |  j |    d j
 |  S(   Ns#   generator must be seeded before usei    i   iĸ  R   (   R   R   R   R   R    R!   R+   t   encryptt   _four_kiblocks_of_zerosR   R#   (   R   R-   R'   R(   t   remaining_bytes(    (    sJ   /usr/lib/python2.7/dist-packages/Crypto/Random/Fortuna/FortunaGenerator.pyR,   u   s    %  i   (   t   __name__t
   __module__t   __doc__R   R   R   R   R/   R   R   R)   R   R"   R,   (    (    (    sJ   /usr/lib/python2.7/dist-packages/Crypto/Random/Fortuna/FortunaGenerator.pyR   %   s   	
					(   t   __revision__t   Crypto.Util.python_compatt   structt   Crypto.Util.numberR   R   R   t   Crypto.UtilR   t   Crypto.CipherR   R   t   objectR   (    (    (    sJ   /usr/lib/python2.7/dist-packages/Crypto/Random/Fortuna/FortunaGenerator.pyt   <module>   s   
