³ò
~ñĴDc           @   sn   d  Z  d e f d     YZ d   Z d   Z d   Z d   Z d   Z d   Z d	   Z	 d d d
  Z d S(   s   Implementation of GCM (Galois/Counter Mode).  See http://csrc.nist.gov/
CryptoToolkit/modes/proposedmodes/gcm/gcm-revised-spec.pdf .t   Objectc           B   s   e  Z d    Z RS(   c         O   s.   | |  _  x | D] } | |  i  | i <q Wd  S(   N(   t   __dict__t   __name__(   t   selft   argst   kwt   arg(    (    s*   /home/ping/web/passpet/darcs/server/gcm.pyt   __init__   s    	 (   R   t
   __module__R   (    (    (    s*   /home/ping/web/passpet/darcs/server/gcm.pyR       s   c         C   s2   g  } t  |  |  D] \ } } | | | Aq ~ S(   N(   t   zip(   t   at   bt   _[1]t   xt   y(    (    s*   /home/ping/web/passpet/darcs/server/gcm.pyt   blockxor
   s    c         C   s   d |  } } d } | d ?| d ?| d ?| d ?} x^ t  d  D]P } | | | ?@o | | N} n | d @d j o | d ?} qB | d ?| A} qB W| S(   s7   Multiply in GF(2^128) modulo x^128 + x^7 + x^2 + x + 1.i    i   i   i   i   i   l	                    (   t   range(   t   Xt   Yt   Zt   Vt   bitt   Rt   i(    (    s*   /home/ping/web/passpet/darcs/server/gcm.pyt   mult   s    " c         C   s   |  d S(   Ni   i   i   (    (   t   n(    (    s*   /home/ping/web/passpet/darcs/server/gcm.pyt   byte   s    c         C   sG   t  g  } t |   D]) \ } } | | t |   d | d >q ~  S(   s:   Convert a block (list of integer bytes) to a long integer.i   i   (   t   sumt	   enumeratet   len(   t   blockR   R   R   (    (    s*   /home/ping/web/passpet/darcs/server/gcm.pyt   tolong   s    c         C   s=   g  } t  | d d d d  D] } | t |  | ? q ~ S(   s:   Convert a long integer to a block (list of integer bytes).i   iĝ˙˙˙(   R   R   (   t   longt
   blockbytesR   t   shift(    (    s*   /home/ping/web/passpet/darcs/server/gcm.pyt   toblock"   s    c      	   C   sn   x& t  |   | d j o |  d 7}  q Wg  } t d t  |   |  D]! } | t t |  | | | ! qF ~ S(   sB   Convert a string to a list of blocks (a block is a list of bytes).i    t    (   R   R   t   mapt   ord(   t   dataR!   R   R   (    (    s*   /home/ping/web/passpet/darcs/server/gcm.pyt   toblocks&   s    c         C   s:   d i  g  } |  D] } | d i  t t |   q ~  S(   s%   Convert a list of blocks to a string.t    (   t   joinR%   t   chr(   t   blocksR   R   (    (    s*   /home/ping/web/passpet/darcs/server/gcm.pyt   tostring-   s    c            s   i  d j o t d   n | d j oB | d j o t d   n t  i t |  i     } n | d } t  i t d d     t | d >d Bd     f d      f d	         f d
   }      f d   } t | |  S(   sŬ  Create a Galois/Counter Mode object with the given cipher.
    Supply a 96-bit long integer for the 'iv' argument or a single block
    as a long integer for the 'nonce' argument (which will be used to
    generate the IV).  The resulting object has a method encrypt() that
    takes a string and yields an encrypted string concatenated with a
    16-byte MAC, and a method decrypt() that takes an encrypted string
    with a 16-byte MAC suffix and yields the decrypted string.i   s)   GCM requires a cipher with 128-bit blockss    either iv or nonce must be giveni   i`   i    i    c            s~    } g  } x[ t  |  d  D]J } | d  t t | d  d d  } | i t |   i |    q Wt |  t |    S(   Ni   iü˙˙˙i   i   (   R(   R#   R   t   appendR   t   encipherR-   R   (   R'   R   t	   newblocksR   (   t   ciphert   Y0(    s*   /home/ping/web/passpet/darcs/server/gcm.pyt	   transformE   s     %#c            sT   d } x0 t  |  d  D] } t | t |  A   } q Wt | t |   d A   S(   Ni    i   i   (   R(   R   R   R   (   R'   R   R   (   t   H(    s*   /home/ping/web/passpet/darcs/server/gcm.pyt   ghashM   s
     c            sG     |   }  |  t   i    A} | t t | d  g  f S(   Ni   (   R   R/   R-   R#   (   R'   t   Ct   T(   R3   R1   R2   R5   (    s*   /home/ping/web/passpet/darcs/server/gcm.pyt   encryptS   s    c            sU   t  t t |   }  |   t   i    A| j o t d   n   |   S(   Ns#   invalid message authentication code(   R   R%   R&   R/   t
   ValueError(   R'   t   macR7   (   R3   R1   R2   R5   (    s*   /home/ping/web/passpet/darcs/server/gcm.pyt   decryptX   s    &Nl               @ (   R!   t	   TypeErrort   NoneR   R/   R#   R    (   R1   t   ivt   nonceR8   R;   (    (   R3   R4   R1   R2   R5   s*   /home/ping/web/passpet/darcs/server/gcm.pyt   GCM1   s    	%
N(   t   __doc__t   objectR    R   R   R   R   R#   R(   R-   R=   R@   (    (    (    s*   /home/ping/web/passpet/darcs/server/gcm.pys   <module>   s   							
