| # |
| # pubkey.py : Internal functions for public key operations |
| # |
| # Part of the Python Cryptography Toolkit |
| # |
| # Distribute and use freely; there are no restrictions on further |
| # dissemination and usage except those imposed by the laws of your |
| # country of residence. This software is provided "as is" without |
| # warranty of fitness for use or suitability for any purpose, express |
| # or implied. Use at your own risk or not at all. |
| # |
| |
| __revision__ = "$Id: pubkey.py,v 1.11 2003/04/03 20:36:14 akuchling Exp $" |
| |
| import types, warnings |
| from Crypto.Util.number import * |
| |
| # Basic public key class |
| class pubkey: |
| def __init__(self): |
| pass |
| |
| def __getstate__(self): |
| """To keep key objects platform-independent, the key data is |
| converted to standard Python long integers before being |
| written out. It will then be reconverted as necessary on |
| restoration.""" |
| d=self.__dict__ |
| for key in self.keydata: |
| if d.has_key(key): d[key]=long(d[key]) |
| return d |
| |
| def __setstate__(self, d): |
| """On unpickling a key object, the key data is converted to the big |
| number representation being used, whether that is Python long |
| integers, MPZ objects, or whatever.""" |
| for key in self.keydata: |
| if d.has_key(key): self.__dict__[key]=bignum(d[key]) |
| |
| def encrypt(self, plaintext, K): |
| """encrypt(plaintext:string|long, K:string|long) : tuple |
| Encrypt the string or integer plaintext. K is a random |
| parameter required by some algorithms. |
| """ |
| wasString=0 |
| if isinstance(plaintext, types.StringType): |
| plaintext=bytes_to_long(plaintext) ; wasString=1 |
| if isinstance(K, types.StringType): |
| K=bytes_to_long(K) |
| ciphertext=self._encrypt(plaintext, K) |
| if wasString: return tuple(map(long_to_bytes, ciphertext)) |
| else: return ciphertext |
| |
| def decrypt(self, ciphertext): |
| """decrypt(ciphertext:tuple|string|long): string |
| Decrypt 'ciphertext' using this key. |
| """ |
| wasString=0 |
| if not isinstance(ciphertext, types.TupleType): |
| ciphertext=(ciphertext,) |
| if isinstance(ciphertext[0], types.StringType): |
| ciphertext=tuple(map(bytes_to_long, ciphertext)) ; wasString=1 |
| plaintext=self._decrypt(ciphertext) |
| if wasString: return long_to_bytes(plaintext) |
| else: return plaintext |
| |
| def sign(self, M, K): |
| """sign(M : string|long, K:string|long) : tuple |
| Return a tuple containing the signature for the message M. |
| K is a random parameter required by some algorithms. |
| """ |
| if (not self.has_private()): |
| raise error, 'Private key not available in this object' |
| if isinstance(M, types.StringType): M=bytes_to_long(M) |
| if isinstance(K, types.StringType): K=bytes_to_long(K) |
| return self._sign(M, K) |
| |
| def verify (self, M, signature): |
| """verify(M:string|long, signature:tuple) : bool |
| Verify that the signature is valid for the message M; |
| returns true if the signature checks out. |
| """ |
| if isinstance(M, types.StringType): M=bytes_to_long(M) |
| return self._verify(M, signature) |
| |
| # alias to compensate for the old validate() name |
| def validate (self, M, signature): |
| warnings.warn("validate() method name is obsolete; use verify()", |
| DeprecationWarning) |
| |
| def blind(self, M, B): |
| """blind(M : string|long, B : string|long) : string|long |
| Blind message M using blinding factor B. |
| """ |
| wasString=0 |
| if isinstance(M, types.StringType): |
| M=bytes_to_long(M) ; wasString=1 |
| if isinstance(B, types.StringType): B=bytes_to_long(B) |
| blindedmessage=self._blind(M, B) |
| if wasString: return long_to_bytes(blindedmessage) |
| else: return blindedmessage |
| |
| def unblind(self, M, B): |
| """unblind(M : string|long, B : string|long) : string|long |
| Unblind message M using blinding factor B. |
| """ |
| wasString=0 |
| if isinstance(M, types.StringType): |
| M=bytes_to_long(M) ; wasString=1 |
| if isinstance(B, types.StringType): B=bytes_to_long(B) |
| unblindedmessage=self._unblind(M, B) |
| if wasString: return long_to_bytes(unblindedmessage) |
| else: return unblindedmessage |
| |
| |
| # The following methods will usually be left alone, except for |
| # signature-only algorithms. They both return Boolean values |
| # recording whether this key's algorithm can sign and encrypt. |
| def can_sign (self): |
| """can_sign() : bool |
| Return a Boolean value recording whether this algorithm can |
| generate signatures. (This does not imply that this |
| particular key object has the private information required to |
| to generate a signature.) |
| """ |
| return 1 |
| |
| def can_encrypt (self): |
| """can_encrypt() : bool |
| Return a Boolean value recording whether this algorithm can |
| encrypt data. (This does not imply that this |
| particular key object has the private information required to |
| to decrypt a message.) |
| """ |
| return 1 |
| |
| def can_blind (self): |
| """can_blind() : bool |
| Return a Boolean value recording whether this algorithm can |
| blind data. (This does not imply that this |
| particular key object has the private information required to |
| to blind a message.) |
| """ |
| return 0 |
| |
| # The following methods will certainly be overridden by |
| # subclasses. |
| |
| def size (self): |
| """size() : int |
| Return the maximum number of bits that can be handled by this key. |
| """ |
| return 0 |
| |
| def has_private (self): |
| """has_private() : bool |
| Return a Boolean denoting whether the object contains |
| private components. |
| """ |
| return 0 |
| |
| def publickey (self): |
| """publickey(): object |
| Return a new key object containing only the public information. |
| """ |
| return self |
| |
| def __eq__ (self, other): |
| """__eq__(other): 0, 1 |
| Compare us to other for equality. |
| """ |
| return self.__getstate__() == other.__getstate__() |