ó
Q'—^c           @   s½   d  Z  d d l Z e j d d k rE e j d d k rE d d l Tn  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ÿÿÿÿNi    i   i   (   t   *(   t
   ceil_shiftt
   exact_log2t	   exact_div(   t   Counter(   t   AESt   AESGeneratorc           B   sm   e  Z d  Z e j Z d Z d Z e 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   s    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(    (    sH   /tmp/pip-unpacked-wheel-owA23s/Crypto/Random/Fortuna/FortunaGenerator.pyt   __init__A   s    (	c         C   sw   |  j  d  k r( t d ƒ |  j |  _  n  |  j t j |  j  | ƒ j ƒ  ƒ |  j ƒ  t	 |  j  ƒ |  j k ss t
 ‚ d  S(   Ns    (   R   R   t   bR   t   _set_keyt   SHAd256R
   t   digestR   t   lenR   (   R   t   seed(    (    sH   /tmp/pip-unpacked-wheel-owA23s/Crypto/Random/Fortuna/FortunaGenerator.pyt   reseedN   s
    #
c         C   s‚   | d k s t  ‚ | d ?} | d @} g  } x* t | ƒ D] } | j |  j d ƒ ƒ q9 W| j |  j | ƒ ƒ t d ƒ j | ƒ S(   Ni    i   i   t    i   iÿÿ i   (   R   t   xranget   appendt   _pseudo_random_dataR   t   join(   R   t   bytest   num_full_blockst	   remaindert   retvalt   i(    (    sH   /tmp/pip-unpacked-wheel-owA23s/Crypto/Random/Fortuna/FortunaGenerator.pyt   pseudo_random_dataV   s    

c         C   s.   | |  _  t j | t j d |  j ƒ|  _ d  S(   NR   (   R   R   R
   t   MODE_CTRR   t   _cipher(   R   R   (    (    sH   /tmp/pip-unpacked-wheel-owA23s/Crypto/Random/Fortuna/FortunaGenerator.pyR   c   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'   (    (    sH   /tmp/pip-unpacked-wheel-owA23s/Crypto/Random/Fortuna/FortunaGenerator.pyR"   g   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 |  ƒ ƒ t
 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'   R(   t   remaining_bytes(    (    sH   /tmp/pip-unpacked-wheel-owA23s/Crypto/Random/Fortuna/FortunaGenerator.pyR,   y   s    %  i   (   t   __name__t
   __module__t   __doc__R   R   R   R   R   R/   R   R   R)   R   R"   R,   (    (    (    sH   /tmp/pip-unpacked-wheel-owA23s/Crypto/Random/Fortuna/FortunaGenerator.pyR   (   s   	
					(   t   __revision__t   syst   version_infot   Crypto.Util.py21compatt   Crypto.Util.py3compatt   structt   Crypto.Util.numberR   R   R   t   Crypto.UtilR   t   Crypto.CipherR   R   t   objectR   (    (    (    sH   /tmp/pip-unpacked-wheel-owA23s/Crypto/Random/Fortuna/FortunaGenerator.pyt   <module>   s   &
