ÿØÿàJFIFÿþ ÿÛC       ÿÛC ÿÀÿÄÿÄ"#QrÿÄÿÄ&1!A"2qQaáÿÚ ?Øy,æ/3JæÝ¹È߲؋5êXw²±ÉyˆR”¾I0ó2—PI¾IÌÚiMö¯–þrìN&"KgX:Šíµ•nTJnLK„…@!‰-ý ùúmë;ºgµŒ&ó±hw’¯Õ@”Ü— 9ñ-ë.²1<yà‚¹ïQÐU„ہ?.’¦èûbß±©Ö«Âw*VŒ) `$‰bØÔŸ’ëXÖ-ËTÜíGÚ3ð«g Ÿ§¯—Jx„–’U/ÂÅv_s(Hÿ@TñJÑãõçn­‚!ÈgfbÓc­:él[ðQe 9ÀPLbÃãCµm[5¿ç'ªjglå‡Ûí_§Úõl-;"PkÞÞÁQâ¼_Ñ^¢SŸx?"¸¦ùY騐ÒOÈ q’`~~ÚtËU¹CڒêV  I1Áß_ÿÙ Bd\Rc@sdZdZddddgZddlTddlmZdefd YZd d Z d Z de fd YZ e Z d S(sP ElGamal public-key algorithm (randomized encryption and signature). Signature algorithm ------------------- The security of the ElGamal signature scheme is based (like DSA) on the discrete logarithm problem (DLP_). Given a cyclic group, a generator *g*, and an element *h*, it is hard to find an integer *x* such that *g^x = h*. The group is the largest multiplicative sub-group of the integers modulo *p*, with *p* prime. The signer holds a value *x* (*0>> from Crypto import Random >>> from Crypto.Random import random >>> from Crypto.PublicKey import ElGamal >>> from Crypto.Util.number import GCD >>> from Crypto.Hash import SHA >>> >>> message = "Hello" >>> key = ElGamal.generate(1024, Random.new().read) >>> h = SHA.new(message).digest() >>> while 1: >>> k = random.StrongRandom().randint(1,key.p-1) >>> if GCD(k,key.p-1)==1: break >>> sig = key.sign(h,k) >>> ... >>> if key.verify(h,sig): >>> print "OK" >>> else: >>> print "Incorrect signature" .. _DLP: http://www.cosic.esat.kuleuven.be/publications/talk-78.pdf .. _CDH: http://en.wikipedia.org/wiki/Computational_Diffie%E2%80%93Hellman_assumption .. _ECRYPT: http://www.ecrypt.eu.org/documents/D.SPA.17.pdf s$Id$tgeneratet constructterrort ElGamalobji(t*(tnumbercBseZRS((t__name__t __module__(((sK/opt/alt/python27/lib64/python2.7/site-packages/Crypto/PublicKey/ElGamal.pyRsscCst}|r|dnxJtt|d|}d|d|_tj|jd|rPqqW|r||dnxtjd|j||_d}t|jd|jdkrd}n|rt|j||jdkrd}n|r&t |jd|jddkr&d}ntj |j|j}|rmt |jd|ddkrmd}n|rPqqW|r|dntjd|jd||_ |r|d nt|j|j |j|_ |S( s'Randomly generate a fresh, new ElGamal key. The key will be safe for use for both encryption and signature (although it should be used for **only one** purpose). :Parameters: bits : int Key length, or size (in bits) of the modulus *p*. Recommended value is 2048. randfunc : callable Random number generation function; it should accept a single integer N and return a string of random data N bytes long. progress_func : callable Optional function that will be called with a short string containing the key parameter currently being generated; it's useful for interactive applications where a user is waiting for a key to be generated. :attention: You should always use a cryptographically secure random number generator, such as the one defined in the ``Crypto.Random`` module; **don't** just use the current time and the ``random`` module. :Return: An ElGamal key object (`ElGamalobj`). sp iitrandfuncsg iisx sy ( RtbignumtgetPrimetpRtisPrimetgetRandomRangetgtpowtdivmodtinversetxty(tbitsRt progress_functobjtqtsafetginv((sK/opt/alt/python27/lib64/python2.7/site-packages/Crypto/PublicKey/ElGamal.pyRws>    $ ) &   cCslt}t|dkr*tdnx;tt|D]'}|j|}t||||q=W|S(s*Construct an ElGamal key from a tuple of valid ElGamal components. The modulus *p* must be a prime. The following conditions must apply: - 1 < g < p-1 - g^{p-1} = 1 mod p - 1 < x < p-1 - g^x = y mod p :Parameters: tup : tuple A tuple of long integers, with 3 or 4 items in the following order: 1. Modulus (*p*). 2. Generator (*g*). 3. Public key (*y*). 4. Private key (*x*). Optional. :Return: An ElGamal key object (`ElGamalobj`). iis%argument for construct() wrong length(ii(Rtlent ValueErrortrangetkeydatatsetattr(ttupRtitfield((sK/opt/alt/python27/lib64/python2.7/site-packages/Crypto/PublicKey/ElGamal.pyRs  cBseZdZddddgZdZdZdZdZd Zd Z d Z d Z d Z dZ dZRS(siClass defining an ElGamal key. :undocumented: __getstate__, __setstate__, __repr__, __getattr__ R RRRcCstj|||S(sREncrypt a piece of data with ElGamal. :Parameter plaintext: The piece of data to encrypt with ElGamal. It must be numerically smaller than the module (*p*). :Type plaintext: byte string or long :Parameter K: A secret number, chosen randomly in the closed range *[1,p-2]*. :Type K: long (recommended) or byte string (not recommended) :Return: A tuple with two items. Each item is of the same type as the plaintext (string or long). :attention: selection of *K* is crucial for security. Generating a random number larger than *p-1* and taking the modulus by *p-1* is **not** secure, since smaller values will occur more frequently. Generating a random number systematically smaller than *p-1* (e.g. *floor((p-1)/8)* random bytes) is also **not** secure. In general, it shall not be possible for an attacker to know the value of any bit of K. :attention: The number *K* shall not be reused for any other operation and shall be discarded immediately. (tpubkeytencrypt(tselft plaintexttK((sK/opt/alt/python27/lib64/python2.7/site-packages/Crypto/PublicKey/ElGamal.pyR#scCstj||S(sPDecrypt a piece of data with ElGamal. :Parameter ciphertext: The piece of data to decrypt with ElGamal. :Type ciphertext: byte string, long or a 2-item tuple as returned by `encrypt` :Return: A byte string if ciphertext was a byte string or a tuple of byte strings. A long otherwise. (R"tdecrypt(R$t ciphertext((sK/opt/alt/python27/lib64/python2.7/site-packages/Crypto/PublicKey/ElGamal.pyR's cCstj|||S(sSign a piece of data with ElGamal. :Parameter M: The piece of data to sign with ElGamal. It may not be longer in bit size than *p-1*. :Type M: byte string or long :Parameter K: A secret number, chosen randomly in the closed range *[1,p-2]* and such that *gcd(k,p-1)=1*. :Type K: long (recommended) or byte string (not recommended) :attention: selection of *K* is crucial for security. Generating a random number larger than *p-1* and taking the modulus by *p-1* is **not** secure, since smaller values will occur more frequently. Generating a random number systematically smaller than *p-1* (e.g. *floor((p-1)/8)* random bytes) is also **not** secure. In general, it shall not be possible for an attacker to know the value of any bit of K. :attention: The number *K* shall not be reused for any other operation and shall be discarded immediately. :attention: M must be be a cryptographic hash, otherwise an attacker may mount an existential forgery attack. :Return: A tuple with 2 longs. (R"tsign(R$tMR&((sK/opt/alt/python27/lib64/python2.7/site-packages/Crypto/PublicKey/ElGamal.pyR)scCstj|||S(sNVerify the validity of an ElGamal signature. :Parameter M: The expected message. :Type M: byte string or long :Parameter signature: The ElGamal signature to verify. :Type signature: A tuple with 2 longs as return by `sign` :Return: True if the signature is correct, False otherwise. (R"tverify(R$R*t signature((sK/opt/alt/python27/lib64/python2.7/site-packages/Crypto/PublicKey/ElGamal.pyR+9s cCsEt|j||j}|t|j||j|j}||fS(N(RRR R(R$R*R&tatb((sK/opt/alt/python27/lib64/python2.7/site-packages/Crypto/PublicKey/ElGamal.pyt_encryptFs#cCs_t|dstdnt|d|j|j}|dt||j|j}|S(NRs(Private key not available in this objectii(thasattrt TypeErrorRRR R(R$R*taxR%((sK/opt/alt/python27/lib64/python2.7/site-packages/Crypto/PublicKey/ElGamal.pyt_decryptKs !cCst|dstdn|jd}t||dkrOtdnt|j||j}||j||}x|dkr||}qW|t|||}||fS(NRs(Private key not available in this objectisBad K value: GCD(K,p-1)!=1i( R0R1R tGCDRRRRR(R$R*R&tp1R-ttR.((sK/opt/alt/python27/lib64/python2.7/site-packages/Crypto/PublicKey/ElGamal.pyt_signRs cCs|ddks'|d|jdkr+dSt|j|d|j}|t|d|d|j|j}t|j||j}||krdSdS(Nii(R RRR(R$R*tsigtv1tv2((sK/opt/alt/python27/lib64/python2.7/site-packages/Crypto/PublicKey/ElGamal.pyt_verify^s'( cCstj|jdS(Ni(RtsizeR (R$((sK/opt/alt/python27/lib64/python2.7/site-packages/Crypto/PublicKey/ElGamal.pyR<hscCst|drdSdSdS(NRii(R0(R$((sK/opt/alt/python27/lib64/python2.7/site-packages/Crypto/PublicKey/ElGamal.pyt has_privatekscCst|j|j|jfS(N(RR RR(R$((sK/opt/alt/python27/lib64/python2.7/site-packages/Crypto/PublicKey/ElGamal.pyt publickeyqs(RRt__doc__RR#R'R)R+R/R3R7R;R<R=R>(((sK/opt/alt/python27/lib64/python2.7/site-packages/Crypto/PublicKey/ElGamal.pyRs       N(R?t __revision__t__all__tCrypto.PublicKey.pubkeyt Crypto.UtilRt ExceptionRtNoneRRR"Rtobject(((sK/opt/alt/python27/lib64/python2.7/site-packages/Crypto/PublicKey/ElGamal.pytjs  J !