ó
Ñs/Uc           @   sú  d  Z  d d l m Z d Z d Z d Z d Z e d d „ Z d e f d „  ƒ  YZ	 d	 e f d
 „  ƒ  YZ
 d e f d „  ƒ  YZ d „  Z e d g  e d ƒ D] Z e e d ƒ ^ q› ƒ Z e d g  e d ƒ D] Z e e d ƒ ^ qÌ ƒ Z e d g  e d ƒ D] Z e e d ƒ ^ qý ƒ Z e d g  e d ƒ D] Z e e d ƒ ^ q.ƒ Z e d g  e d ƒ D] Z e e d ƒ ^ q_ƒ Z e d g  e d ƒ D] Z e e d ƒ ^ qƒ Z e d d j d ƒ ƒ Z e d d j d ƒ ƒ Z e d d j d ƒ ƒ Z d S(   s~  Simple AES cipher implementation in pure Python following PEP-272 API

Homepage: https://bitbucket.org/intgr/pyaes/

The goal of this module is to be as fast as reasonable in Python while still
being Pythonic and readable/understandable. It is licensed under the permissive
MIT license.

Hopefully the code is readable and commented enough that it can serve as an
introduction to the AES cipher for Python coders. In fact, it should go along
well with the Stick Figure Guide to AES:
http://www.moserware.com/2009/09/stick-figure-guide-to-advanced.html

Contrary to intuition, this implementation numbers the 4x4 matrices from top to
bottom for efficiency reasons::

  0  4  8 12
  1  5  9 13
  2  6 10 14
  3  7 11 15

Effectively it's the transposition of what you'd expect. This actually makes
the code simpler -- except the ShiftRows step, but hopefully the explanation
there clears it up.

iÿÿÿÿ(   t   arrayi   i   i   c         C   s`   | t  k r t t |  ƒ ƒ S| t k rV | d  k rC t d ƒ ‚ n  t t |  ƒ | ƒ St ‚ d  S(   Ns   CBC mode needs an IV value!(   t   MODE_ECBt   ECBModet   AESt   MODE_CBCt   Nonet
   ValueErrort   CBCModet   NotImplementedError(   t   keyt   modet   IV(    (    s/   /var/www/c4bv.valis/web2py/gluon/contrib/aes.pyt   new>   s    R   c           B   sq   e  Z d  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z	 d „  Z
 d	 „  Z d
 „  Z d „  Z RS(   i   c         C   s   |  j  | ƒ d  S(   N(   t   setkey(   t   selfR	   (    (    s/   /var/www/c4bv.valis/web2py/gluon/contrib/aes.pyt   __init__N   s    c         C   sƒ   | |  _  t | ƒ |  _ |  j d k r3 d |  _ nB |  j d k rN d |  _ n' |  j d k ri d |  _ n t d ƒ ‚ |  j ƒ  d S(	   s(   Sets the key and performs key expansion.i   i
   i   i   i    i   s%   Key length must be 16, 24 or 32 bytesN(   R	   t   lent   key_sizet   roundsR   t
   expand_key(   R   R	   (    (    s/   /var/www/c4bv.valis/web2py/gluon/contrib/aes.pyR   Q   s    	c      	   C   sú  t  d |  j ƒ } |  j d k r* d } n |  j d k rB d } n d } | d } x˜t d d	 ƒ D]‡} | d d
 !| d d !} x& t d
 ƒ D] } t | | | | <q W| d t | A| d <xT t d
 ƒ D]F } x0 t d
 ƒ D]" } | | c | |  j | N<qß W| j | ƒ qÌ Wt | ƒ |  j d |  j	 k r:Pn  |  j d k r’x6 t d
 ƒ D]( } t | | | |  j | A| | <qVW| j | ƒ n  xT t | ƒ D]F } x0 t d
 ƒ D]" } | | c | |  j | N<q²W| j | ƒ qŸWqb W| |  _
 d S(   s?   Performs AES key expansion on self.key and stores in self.exkeyt   Bi   i    i   i   i   iüÿÿÿi   i   i   i    N(   R    R	   R   t   xranget   aes_sboxt   aes_Rcont   extendR   R   t
   block_sizet   exkey(   R   R   t	   extra_cntt   wordt   it   jt   z(    (    s/   /var/www/c4bv.valis/web2py/gluon/contrib/aes.pyR   b   s6    		
  & c         C   sF   | d } |  j  } x, t d ƒ D] } | | c | | | N<q  Wd S(   sF   AddRoundKey step in AES. This is where the key is mixed into plaintexti   N(   R   R   (   R   t   blockt   roundt   offsetR   R   (    (    s/   /var/www/c4bv.valis/web2py/gluon/contrib/aes.pyt   add_round_key£   s    
	c         C   s-   x& t  d ƒ D] } | | | | | <q Wd S(   s•   SubBytes step, apply S-box to all bytes

        Depending on whether encrypting or decrypting, a different sbox array
        is passed in.
        i   N(   R   (   R   R    t   sboxR   (    (    s/   /var/www/c4bv.valis/web2py/gluon/contrib/aes.pyt	   sub_bytes®   s    c         C   s¾   | d | d | d | d f \ | d <| d <| d <| d <| d | d | d | d f \ | d <| d <| d <| d <| d	 | d
 | d | d f \ | d
 <| d <| d <| d	 <d S(   sÏ  ShiftRows step. Shifts 2nd row to left by 1, 3rd row by 2, 4th row by 3

        Since we're performing this on a transposed matrix, cells are numbered
        from top to bottom::

          0  4  8 12   ->    0  4  8 12    -- 1st row doesn't change
          1  5  9 13   ->    5  9 13  1    -- row shifted to left by 1 (wraps around)
          2  6 10 14   ->   10 14  2  6    -- shifted by 2
          3  7 11 15   ->   15  3  7 11    -- shifted by 3
        i   i	   i   i   i
   i   i   i   i   i   i   i   N(    (   R   t   b(    (    s/   /var/www/c4bv.valis/web2py/gluon/contrib/aes.pyt
   shift_rowsº   s    >>c         C   s¾   | d | d | d | d f \ | d <| d <| d <| d <| d | d | d | d f \ | d <| d <| d <| d <| d	 | d
 | d | d f \ | d <| d	 <| d
 <| d <d S(   sE   Similar to shift_rows above, but performed in inverse for decryption.i   i   i	   i   i   i   i
   i   i   i   i   i   N(    (   R   R&   (    (    s/   /var/www/c4bv.valis/web2py/gluon/contrib/aes.pyt   shift_rows_invÌ   s    >>c   
      C   sï   t  } t } xÜ t d ƒ D]Î } | d } | | | | d | | d | | d f \ } } } }	 | | |	 A| A| | A| | <| | | A|	 A| | A| | d <| | | A| A| |	 A| | d <| |	 | A| A| | A| | d <q Wd S(   s0   MixColumns step. Mixes the values in each columni   i   i   i   N(   t   gf_mul_by_2t   gf_mul_by_3R   (
   R   R    t   mul_by_2t   mul_by_3R   t   colt   v0t   v1t   v2t   v3(    (    s/   /var/www/c4bv.valis/web2py/gluon/contrib/aes.pyt   mix_columnsÕ   s    
""c         C   s  t  } t } t } t } xü t d ƒ D]î } | d } | | | | d | | d | | d f \ } }	 }
 } | | | | A| |
 A| |	 A| | <| |	 | | A| | A| |
 A| | d <| |
 | |	 A| | A| | A| | d <| | | |
 A| |	 A| | A| | d <q% Wd S(   sF   Similar to mix_columns above, but performed in inverse for decryption.i   i   i   i   N(   t   gf_mul_by_9t   gf_mul_by_11t   gf_mul_by_13t   gf_mul_by_14R   (   R   R    t   mul_9t   mul_11t   mul_13t   mul_14R   R-   R.   R/   R0   R1   (    (    s/   /var/www/c4bv.valis/web2py/gluon/contrib/aes.pyt   mix_columns_invì   s    
&**c         C   s›   |  j  | d ƒ xT t d |  j ƒ D]@ } |  j | t ƒ |  j | ƒ |  j | ƒ |  j  | | ƒ q# W|  j | t ƒ |  j | ƒ |  j  | |  j ƒ d S(   s6   Encrypts a single block. This is the main AES functioni    i   N(   R#   R   R   R%   R   R'   R2   (   R   R    R!   (    (    s/   /var/www/c4bv.valis/web2py/gluon/contrib/aes.pyt   encrypt_block  s    c         C   s¢   |  j  | |  j ƒ x[ t |  j d d d ƒ D]@ } |  j | ƒ |  j | t ƒ |  j  | | ƒ |  j | ƒ q- W|  j | ƒ |  j | t ƒ |  j  | d ƒ d S(   sA   Decrypts a single block. This is the main AES decryption functioni   i    iÿÿÿÿN(   R#   R   R   R(   R%   t   aes_inv_sboxR;   (   R   R    R!   (    (    s/   /var/www/c4bv.valis/web2py/gluon/contrib/aes.pyt   decrypt_block  s     (   t   __name__t
   __module__R   R   R   R   R#   R%   R'   R(   R2   R;   R<   R>   (    (    (    s/   /var/www/c4bv.valis/web2py/gluon/contrib/aes.pyR   K   s   			A								R   c           B   s2   e  Z d  Z d „  Z d „  Z d „  Z d „  Z RS(   sÆ   Electronic CodeBook (ECB) mode encryption.

    Basically this mode applies the cipher function to each block individually;
    no feedback is done. NB! This is insecure for almost all purposes
    c         C   s   | |  _  | j |  _ d  S(   N(   t   cipherR   (   R   RA   (    (    s/   /var/www/c4bv.valis/web2py/gluon/contrib/aes.pyR   4  s    	c         C   s™   t  | ƒ |  j d k r( t d ƒ ‚ n  |  j } t d | ƒ } xL t d t  | ƒ | ƒ D]2 } | | | | !} | | ƒ | | | | | +qY W| j ƒ  S(   s(   Perform ECB mode with the given functioni    s'   Plaintext length must be multiple of 16R   (   R   R   R   R    R   t   tostring(   R   t   datat
   block_funcR   R"   R    (    (    s/   /var/www/c4bv.valis/web2py/gluon/contrib/aes.pyt   ecb8  s    	
c         C   s   |  j  | |  j j ƒ S(   s   Encrypt data in ECB mode(   RE   RA   R<   (   R   RC   (    (    s/   /var/www/c4bv.valis/web2py/gluon/contrib/aes.pyt   encryptH  s    c         C   s   |  j  | |  j j ƒ S(   s   Decrypt data in ECB mode(   RE   RA   R>   (   R   RC   (    (    s/   /var/www/c4bv.valis/web2py/gluon/contrib/aes.pyt   decryptM  s    (   R?   R@   t   __doc__R   RE   RF   RG   (    (    (    s/   /var/www/c4bv.valis/web2py/gluon/contrib/aes.pyR   -  s
   			R   c           B   s)   e  Z d  Z d „  Z d „  Z d „  Z RS(   sÕ   Cipher Block Chaining (CBC) mode encryption. This mode avoids content leaks.

    In CBC encryption, each plaintext block is XORed with the ciphertext block
    preceding it; decryption is simply the inverse.
    c         C   s+   | |  _  | j |  _ t d | ƒ |  _ d  S(   NR   (   RA   R   R    R   (   R   RA   R   (    (    s/   /var/www/c4bv.valis/web2py/gluon/contrib/aes.pyR   ^  s    	c         C   sß   |  j  } t | ƒ | d k r. t d ƒ ‚ n  t d | ƒ } |  j } xƒ t d t | ƒ | ƒ D]i } | | | | !} x( t | ƒ D] } | | c | | N<qƒ W|  j j | ƒ | | | | | +| } q_ W| |  _ | j ƒ  S(   s   Encrypt data in CBC modei    s'   Plaintext length must be multiple of 16R   (	   R   R   R   R    R   R   RA   R<   RB   (   R   RC   R   R   R"   R    R   (    (    s/   /var/www/c4bv.valis/web2py/gluon/contrib/aes.pyRF   c  s    		
	c         C   sæ   |  j  } t | ƒ | d k r. t d ƒ ‚ n  t d | ƒ } |  j } xŠ t d t | ƒ | ƒ D]p } | | | | !} | } |  j j | ƒ x( t | ƒ D] } | | c | | N<qš W| | | | | +| } q_ W| |  _ | j ƒ  S(   s   Decrypt data in CBC modei    s(   Ciphertext length must be multiple of 16R   (	   R   R   R   R    R   R   RA   R>   RB   (   R   RC   R   R   R"   t   ctextR    R   (    (    s/   /var/www/c4bv.valis/web2py/gluon/contrib/aes.pyRG   {  s    		
	(   R?   R@   RH   R   RF   RG   (    (    (    s/   /var/www/c4bv.valis/web2py/gluon/contrib/aes.pyR   T  s   		c         C   s]   d } xL | rT | d @r& | |  N} n  |  d K}  |  d @rG |  d N}  n  | d L} q	 W| d @S(   s#   Galois Field multiplicaiton for AESi    i   i   i   iÿ   (    (   t   aR&   t   p(    (    s/   /var/www/c4bv.valis/web2py/gluon/contrib/aes.pyt   galois_multiply™  s    	


R   i   i   i	   i   i   i   t   637c777bf26b6fc53001672bfed7ab76ca82c97dfa5947f0add4a2af9ca472c0b7fd9326363ff7cc34a5e5f171d8311504c723c31896059a071280e2eb27b27509832c1a1b6e5aa0523bd6b329e32f8453d100ed20fcb15b6acbbe394a4c58cfd0efaafb434d338545f9027f503c9fa851a3408f929d38f5bcb6da2110fff3d2cd0c13ec5f974417c4a77e3d645d197360814fdc222a908846eeb814de5e0bdbe0323a0a4906245cc2d3ac629195e479e7c8376d8dd54ea96c56f4ea657aae08ba78252e1ca6b4c6e8dd741f4bbd8b8a703eb5664803f60e613557b986c11d9ee1f8981169d98e949b1e87e9ce5528df8ca1890dbfe6426841992d0fb054bb16t   hext   52096ad53036a538bf40a39e81f3d7fb7ce339829b2fff87348e4344c4dee9cb547b9432a6c2233dee4c950b42fac34e082ea16628d924b2765ba2496d8bd12572f8f66486689816d4a45ccc5d65b6926c704850fdedb9da5e154657a78d9d8490d8ab008cbcd30af7e45805b8b34506d02c1e8fca3f0f02c1afbd0301138a6b3a9111414f67dcea97f2cfcef0b4e67396ac7422e7ad3585e2f937e81c75df6e47f11a711d29c5896fb7620eaa18be1bfc563e4bc6d279209adbc0fe78cd5af41fdda8338807c731b11210592780ec5f60517fa919b54a0d2de57a9f93c99cefa0e03b4dae2af5b0c8ebbb3c83539961172b047eba77d626e169146355210c7dtþ  8d01020408102040801b366cd8ab4d9a2f5ebc63c697356ad4b37dfaefc5913972e4d3bd61c29f254a943366cc831d3a74e8cb8d01020408102040801b366cd8ab4d9a2f5ebc63c697356ad4b37dfaefc5913972e4d3bd61c29f254a943366cc831d3a74e8cb8d01020408102040801b366cd8ab4d9a2f5ebc63c697356ad4b37dfaefc5913972e4d3bd61c29f254a943366cc831d3a74e8cb8d01020408102040801b366cd8ab4d9a2f5ebc63c697356ad4b37dfaefc5913972e4d3bd61c29f254a943366cc831d3a74e8cb8d01020408102040801b366cd8ab4d9a2f5ebc63c697356ad4b37dfaefc5913972e4d3bd61c29f254a943366cc831d3a74e8cbN(   RH   R    R   R   R   R   R   R   t   objectR   R   R   RL   t   ranget   xR)   R*   R3   R4   R5   R6   t   decodeR   R=   R   (    (    (    s/   /var/www/c4bv.valis/web2py/gluon/contrib/aes.pyt   <module>   s2   â'E	111111
