ó õùPc@sƒdZdZddddgZddlTddlmZdefd „ƒ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__(((s3..\python\site-packages\Crypto\PublicKey\ElGamal.pyRsscCsàtƒ}|r|dƒnxItt|d|ƒƒ}d|d|_tj|jd|ƒrPqq|r{|dƒnxûtjd|j|ƒ|_d}t|jd|jƒdkrÆd}n|rót|j||jƒdkród}n|r%t |jd|jƒddkr%d}ntj |j|jƒ}|rlt |jd|ƒddkrld}n|r~Pq~q~|rŒ|dƒntjd|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((s3..\python\site-packages\Crypto\PublicKey\ElGamal.pyRws>    $ ) &   cCsltƒ}t|ƒdkr*tdƒ‚nx;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((s3..\python\site-packages\Crypto\PublicKey\ElGamal.pyRÁs  cBsƒeZdZddddgZd„Zd„Zd„Zd„Zd „Zd „Z d „Z d „Z d „Z d„Z d„ZRS(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((s3..\python\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((s3..\python\site-packages\Crypto\PublicKey\ElGamal.pyR's cCstj|||ƒS(s„Sign 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&((s3..\python\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((s3..\python\site-packages\Crypto\PublicKey\ElGamal.pyR+9s cCsEt|j||jƒ}|t|j||jƒ|j}||fS(N(RRR R(R$R*R&tatb((s3..\python\site-packages\Crypto\PublicKey\ElGamal.pyt_encryptFs#cCs_t|dƒstdƒ‚nt|d|j|jƒ}|dt||jƒ|j}|S(NRs(Private key not available in this objectii(thasattrt TypeErrorRRR R(R$R*taxR%((s3..\python\site-packages\Crypto\PublicKey\ElGamal.pyt_decryptKs !cCsºt|dƒstdƒ‚n|jd}t||ƒdkrOtdƒ‚nt|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.((s3..\python\site-packages\Crypto\PublicKey\ElGamal.pyt_signRs cCs›|ddks'|d|jdkr+dSt|j|d|jƒ}|t|d|d|jƒ|j}t|j||jƒ}||kr—dSdS(Nii(R RRR(R$R*tsigtv1tv2((s3..\python\site-packages\Crypto\PublicKey\ElGamal.pyt_verify^s'( cCstj|jƒdS(Ni(RtsizeR (R$((s3..\python\site-packages\Crypto\PublicKey\ElGamal.pyR<hscCst|dƒrdSdSdS(NRii(R0(R$((s3..\python\site-packages\Crypto\PublicKey\ElGamal.pyt has_privatekscCst|j|j|jfƒS(N(RR RR(R$((s3..\python\site-packages\Crypto\PublicKey\ElGamal.pyt publickeyqs(RRt__doc__RR#R'R)R+R/R3R7R;R<R=R>(((s3..\python\site-packages\Crypto\PublicKey\ElGamal.pyRâs       N(R?t __revision__t__all__tCrypto.PublicKey.pubkeyt Crypto.UtilRt ExceptionRtNoneRRR"Rtobject(((s3..\python\site-packages\Crypto\PublicKey\ElGamal.pytjs  J !“