This patch does a few things to simplify the public key classes
(RSA, DSA and ElGamal):
* It removes the Crypto.PublicKey.pubkey module. The 3 classes
do not have an ancestor anymore.
* Methods sign(), verify(), encrypt(), and decrypt() are removed.
* Methods blind() and unblind() are removed.
* Methods can_sign() and can_encrypt() are removed.
* The 3 classes cannot be pickled anymore.
This patch makes it possible to generate a new DSA key so that it uses
a set of pre-defined domain parameters.
For instance, it is possible to generate 2 distinct DSA keys that
share the same domain parameters:
>> key_one = DSA.generate(2048)
>> key_two = DSA.generate(2048, domain=key_one.domain())
This patch introduces a new module (Crypto.Signature.DSS)
with a less error prone API for performing DSA signatures.
Similarly to Crypto.Signature.PKCS1_PSS, the module
creates a signer object that only works with hash objects,
not directly with messages.
Additionally, the caller does not need to provide any RNG.
The module will use the default one and will correctly pick
the critical nonce K.
Example of API usage:
>>> from Crypto.Signature.DSS
>>> from Crypto.Hash import SHA256
>>> from Crypto.PublicKey import DSA
>>>
>>> message = b'I give my permission to order #4355'
>>> key = DSA.importKey(open('privkey.der').read())
>>> h = SHA256.new(message)
>>> signer = DSS.new(key)
>>> signature = signer.sign(h)
This patch strenghten the DSA signing code against
side-channel attacks.
The DSA signing formulae:
r = (g^{k} mod p) mod q
s = k^{-1} * (H(m) + r*x) mod q
becomes:
b = random in [1..q)
r = (g^{k} mod p) mod q
s = (b * k)^{-1} * (b*H(m) + r*(b*x)) mod q
In this way we avoid that the secret (x) gets multiplied
by a random factor (r) which is immediately disclosed
to an attacker (which we assume can both collect (r) and
also monitor the side-channel produced by the multiplication).
See also attack DSA_2 in:
"Minimum Requirements for Evaluating Side-Channel Attack Resistance
of RSA, DSA and Diffie-Hellman Key Exchange Implementations", BSI
When the various components are assembled into an RSA,
DSA or ElGamal key via the construct() method, we must verify
as much as possible if the result is indeed a valid key.
This patch adds methods importKey() to DSA module
and exportKey() to _DSAobj object.
Public and private keys can be imported/exported
in a variety of formats:
* DER vs PEM
* PKCS#8 vs OpenSSL vs OpenSSH/OpenSSL
* Encrypted vs clear
o _fastmath now builds and runs on PY3K
o Changes to setup.py to allow /usr/include for gmp.h
o Changes to setup.py to allow linking fastmath w/ static mpir
on Windows without warning messages
o Changes to test_DSA/test_RSA to throw an exception if _fastmath
is present but cannot be imported (due to an issue building
_fastmath or the shared gmp/mpir libraries not being reachable)
o number.py has the code to flag a failing _fastmath, but that
code is commented out for a better runtime experience
o Clean up the if for py21compat import - should have been == not is
o Clean up some '== None' occurences, now 'is None' instead
In an attempt to simplify the copyright status of PyCrypto, I'm placing my
code into the public domain, and encouraging other contributors to do the
same.
I have used a public domain dedication that was recommended in a book on FOSS legal
issues[1], followed by the warranty disclaimer boilerplate from the MIT license.
[1] _Intellectual Property and Open Source: A Practical Guide to Protecting
Code_, a book written by Van Lindberg and published by O'Reilly Media.
(ISBN 978-0-596-51796-0)
This will avoid the previous situation where scripts like the old "test.py"
get included accidentally in a release. It also frees us to put additional
build scripts in the top-level directory of the source tree.