³ò
’K¯Dc           @   s[   d  Z  d Z d Z d d k l Z d e f d „  ƒ  YZ d d d „  ƒ  YZ e d	 „ Z	 d
 S(   s  This module implements SRP-6a (see http://srp.stanford.edu/design.html).
Variable names used here match those used in the description on that page:

    N       a large prime number (N = 2q + 1, where q is prime)
    g       a generator (primitive root) modulo N
    k       a multiplier parameter (k = H(N, g) in SRP-6a)
    s       a random string used as the user's salt
    I       the username
    p       the user's cleartext password
    H()     a one-way hash function
    u       a random scrambling parameter (public)
    a, b    ephemeral private keys, generated randomly and kept secret
    A, B    corresponding ephemeral public keys
    x       a private key derived from p and s
    v       the host's password verifier
    K       the session key

The host stores passwords using the following formula:

    x = H(s, p)               (s is chosen randomly)
    v = g^x                   (computes password verifier)

The host then keeps {I, s, v} in its password database. The authentication
protocol itself goes as follows:

User -> Host: I, A = g^a                  (identifies self, a = random number)
Host -> User: s, B = kv + g^b             (sends salt, b = random number)

        Both: u = H(A, B)

        User: x = H(s, p)                 (user enters password)
        User: S = (B - kg^x) ^ (a + ux)   (computes session key)
        User: K = H(S)

        Host: S = (Av^u) ^ b              (computes session key)
        Host: K = H(S)

Now the two parties have a shared, strong session key K. To complete
authentication, they need to prove to each other that their keys match.
One possible way:

User -> Host:  M = H(H(N) xor H(g), H(I), s, A, B, K)
Host -> User:  H(A, M, K)

The two parties also employ the following safeguards:

    1.  The user will abort if he receives B == 0 (mod N) or u == 0.
    2.  The host will abort if it detects that A == 0 (mod N).
    3.  The user must show his proof of K first. If the server detects
        that the user's proof is incorrect, it must abort without showing
        its own proof of K. 
s   Ka-Ping Yees
   2006-06-25iÿÿÿÿ(   t	   randranget   SRPErrorc           B   s   e  Z RS(    (   t   __name__t
   __module__(    (    (    s,   /home/ping/web/passpet/darcs/server/srp6a.pyR   ;   s    t   Objectc           B   s   e  Z d  „  Z RS(   c         O   s.   | |  _  x | D] } | |  i  | i <q Wd  S(   N(   t   __dict__R   (   t   selft   argst   kwt   arg(    (    s,   /home/ping/web/passpet/darcs/server/srp6a.pyt   __init__>   s    	 (   R   R   R
   (    (    (    s,   /home/ping/web/passpet/darcs/server/srp6a.pyR   =   s   c            sß   d „  ‰ ‡ ‡ ‡ f d †  ‰ ‡ ‡ f d †  ‰
 ‡
 ‡ f d †  ‰	 ˆ ˆ ˆ ƒ ‰ ‡ f d †  ‰  d „  ‰ ‡ ‡  ‡ ‡	 f d †  } ‡
 ‡  ‡ ‡ ‡ ‡ ‡ ‡ ‡	 f	 d †  } ‡
 ‡  ‡ ‡ ‡ ‡ ‡ ‡ ‡	 f	 d	 †  } t  | | | ƒ S(
   Nc         S   s/   d } x" |  D] } | d >t  | ƒ } q W| S(   Nl    l    (   t   ord(   t   strt   valuet   ch(    (    s,   /home/ping/web/passpet/darcs/server/srp6a.pyR   D   s
     c             s&   ˆ ˆ  d i  t t |  ƒ ƒ ƒ ƒ ˆ S(   Nt   -(   t   joint   mapR   (   t   values(   t   hashR   t   N(    s,   /home/ping/web/passpet/darcs/server/srp6a.pyt   HJ   s    c            s   ˆ  |  | ˆ ƒ S(   N(    (   t   baset   exponent(   t   _powR   (    s,   /home/ping/web/passpet/darcs/server/srp6a.pyt   powM   s    c            s   ˆ  ˆ |  ƒ S(   N(    (   R   (   R   t   g(    s,   /home/ping/web/passpet/darcs/server/srp6a.pyt   expP   s    c              s   t  d ˆ  ƒ S(   Ni   (   R    (    (   R   (    s,   /home/ping/web/passpet/darcs/server/srp6a.pyt   randomU   s    c         S   s   |  p t  | ƒ ‚ n d  S(   N(   R   (   t	   conditiont	   exception(    (    s,   /home/ping/web/passpet/darcs/server/srp6a.pyt   ensureX   s    c            s:   ˆ |  ƒ } ˆ ƒ  } ˆ  | | ƒ } ˆ | ƒ } | | f S(   N(    (   t   passwordt   pt   st   xt   v(   R   R   R   R   (    s,   /home/ping/web/passpet/darcs/server/srp6a.pyt   setup\   s
    	c         3   s\  ˆ |  ƒ ˆ } ˆ | ƒ ˆ } g  } | i  Vd Vˆ ƒ  } ˆ | ƒ } | Vd  V| i d ƒ ˆ } d  V| i d ƒ ˆ }	 ˆ |	 d ƒ ˆ | |	 ƒ }
 ˆ |
 d ƒ ˆ | | ƒ } ˆ  |	 ˆ ˆ | ƒ | |
 | ƒ } ˆ | ƒ } ˆ ˆ ˆ ƒ ˆ ˆ ƒ Aˆ | ƒ | | |	 | ƒ } | Vd  V| i d ƒ } ˆ | ˆ | | | ƒ j d ƒ | | _ d  S(   Ni   i    s   received zero for Bs   received zero for us   H(A, M, K) did not match(   t   appendt   Nonet   popt   key(   t   usernameR    t   Rt   IR!   t   queuet   at   AR"   t   Bt   uR#   t   St   Kt   Mt   remote_HAMK(	   R   R   R   R   R   t   kR   R   R   (    s,   /home/ping/web/passpet/darcs/server/srp6a.pyt   loginh   s*    	%1c         3   sd  ˆ |  ƒ ˆ } | ˆ } | ˆ } g  } | i  Vd  V| i d ƒ } | d j oý d  V| i d ƒ ˆ } ˆ | d ƒ ˆ ƒ  } ˆ | ˆ | ƒ ˆ }	 | V|	 Vˆ | |	 ƒ }
 ˆ  | ˆ  | |
 ƒ | ƒ } ˆ | ƒ } ˆ ˆ ˆ ƒ ˆ ˆ ƒ Aˆ | ƒ | | |	 | ƒ } d  V| i d ƒ } ˆ | | j d ƒ ˆ | | | ƒ V| | _ n t d | ƒ ‚ d  S(   Ni    i   s   received zero for As   M did not matchs   protocol %d is unsupported(   R&   R'   R(   R)   R   (   R*   R"   R$   R+   R,   R-   t   protocolR/   t   bR0   R1   R2   R3   R4   t   remote_M(	   R   R   R   R   R   R6   R   R   R   (    s,   /home/ping/web/passpet/darcs/server/srp6a.pyt   authenticate‚   s,    

	1(   R   (   R   R   R   R   R%   R7   R;   (    (   R   R   R   R   R6   R   R   R   R   R   R   s,   /home/ping/web/passpet/darcs/server/srp6a.pyt   SRPC   s    		''N(    (
   t   __doc__t
   __author__t   __date__R   R    t	   ExceptionR   R   R   R<   (    (    (    s,   /home/ping/web/passpet/darcs/server/srp6a.pys   <module>4   s   
