ó
Bd\Rc           @   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 m Z d d l Z e d ƒ e d ƒ d d e	 e	 e	 d	 „ Z
 e	 d
 „ Z d S(   s«  Fast counter functions for CTR cipher modes.

CTR is a chaining mode for symmetric block encryption or decryption.
Messages are divideded into blocks, and the cipher operation takes
place on each block using the secret key and a unique *counter block*.

The most straightforward way to fulfil the uniqueness property is
to start with an initial, random *counter block* value, and increment it as
the next block is processed.

The block ciphers from `Crypto.Cipher` (when configured in *MODE_CTR* mode)
invoke a callable object (the *counter* parameter) to get the next *counter block*.
Unfortunately, the Python calling protocol leads to major performance degradations.

The counter functions instantiated by this module will be invoked directly
by the ciphers in `Crypto.Cipher`. The fact that the Python layer is bypassed
lead to more efficient (and faster) execution of CTR cipher modes.

An example of usage is the following:

    >>> from Crypto.Cipher import AES
    >>> from Crypto.Util import Counter
    >>>
    >>> pt = b' '*1000000
    >>> ctr = Counter.new(128)
    >>> cipher = AES.new(b' '*16, AES.MODE_CTR, counter=ctr)
    >>> ct = cipher.encrypt(pt)

:undocumented: __package__
iÿÿÿÿNi    i   i   (   t   *(   t   _countert    c         C   sß   t  |  d ƒ \ } }	 |	 d k r7 t d |  f ƒ ‚ n  | d k  rR t d ƒ ‚ n | d k rm t d ƒ ‚ n  t | | | ƒ }
 | r° t j t | ƒ t | ƒ |
 d | d	 | ƒSt j t | ƒ t | ƒ |
 d | d	 | ƒSd
 S(   sc  Create a stateful counter block function suitable for CTR encryption modes.

    Each call to the function returns the next counter block.
    Each counter block is made up by three parts::
 
      prefix || counter value || postfix

    The counter value is incremented by one at each call.

    :Parameters:
      nbits : integer
        Length of the desired counter, in bits. It must be a multiple of 8.
      prefix : byte string
        The constant prefix of the counter block. By default, no prefix is
        used.
      suffix : byte string
        The constant postfix of the counter block. By default, no suffix is
        used.
      initial_value : integer
        The initial value of the counter. Default value is 1.
      little_endian : boolean
        If True, the counter number will be encoded in little endian format.
        If False (default), in big endian format.
      allow_wraparound : boolean
        If True, the function will raise an *OverflowError* exception as soon
        as the counter wraps around. If False (default), the counter will
        simply restart from zero.
      disable_shortcut : boolean
        If True, do not make ciphers from `Crypto.Cipher` bypass the Python
        layer when invoking the counter block function.
        If False (default), bypass the Python layer.
    :Returns:
      The counter block function.
    i   i    s%   nbits must be a multiple of 8; got %di   s   nbits too smalliÿÿ  s   nbits too larget   allow_wraparoundt   disable_shortcutN(   t   divmodt
   ValueErrort   _encodeR   t   _newLEt   bstrt   _newBE(   t   nbitst   prefixt   suffixt   initial_valuet   overflowt   little_endianR   R   t   nbytest	   remaindert   initval(    (    s2   lib/python2.7/site-packages/Crypto/Util/Counter.pyt   new?   s    %+c         C   s€   g  } t  |  ƒ }  xX t | ƒ D]J } | rE | j t |  d @ƒ ƒ n | j d t |  d @ƒ ƒ |  d L}  q Wt d ƒ j | ƒ S(   Niÿ   i    i   R   (   t   longt   ranget   appendt   bchrt   insertt   bt   join(   t   nR   R   t   retvalt   i(    (    s2   lib/python2.7/site-packages/Crypto/Util/Counter.pyR   t   s    (   t   __doc__t   syst   version_infot   Crypto.Util.py21compatt   Crypto.Util.py3compatt   Crypto.UtilR   t   structR   t   FalseR   R   (    (    (    s2   lib/python2.7/site-packages/Crypto/Util/Counter.pyt   <module>5   s   &
*5