[3] | 1 | # |
---|
| 2 | # pubkey.py : Internal functions for public key operations |
---|
| 3 | # |
---|
| 4 | # Part of the Python Cryptography Toolkit |
---|
| 5 | # |
---|
| 6 | # Distribute and use freely; there are no restrictions on further |
---|
| 7 | # dissemination and usage except those imposed by the laws of your |
---|
| 8 | # country of residence. This software is provided "as is" without |
---|
| 9 | # warranty of fitness for use or suitability for any purpose, express |
---|
| 10 | # or implied. Use at your own risk or not at all. |
---|
| 11 | # |
---|
| 12 | |
---|
| 13 | __revision__ = "$Id: pubkey.py,v 1.11 2003/04/03 20:36:14 akuchling Exp $" |
---|
| 14 | |
---|
| 15 | import types, warnings |
---|
| 16 | from Crypto.Util.number import * |
---|
| 17 | |
---|
| 18 | # Basic public key class |
---|
| 19 | class pubkey: |
---|
| 20 | def __init__(self): |
---|
| 21 | pass |
---|
| 22 | |
---|
| 23 | def __getstate__(self): |
---|
| 24 | """To keep key objects platform-independent, the key data is |
---|
| 25 | converted to standard Python long integers before being |
---|
| 26 | written out. It will then be reconverted as necessary on |
---|
| 27 | restoration.""" |
---|
| 28 | d=self.__dict__ |
---|
| 29 | for key in self.keydata: |
---|
| 30 | if d.has_key(key): d[key]=long(d[key]) |
---|
| 31 | return d |
---|
| 32 | |
---|
| 33 | def __setstate__(self, d): |
---|
| 34 | """On unpickling a key object, the key data is converted to the big |
---|
| 35 | number representation being used, whether that is Python long |
---|
| 36 | integers, MPZ objects, or whatever.""" |
---|
| 37 | for key in self.keydata: |
---|
| 38 | if d.has_key(key): self.__dict__[key]=bignum(d[key]) |
---|
| 39 | |
---|
| 40 | def encrypt(self, plaintext, K): |
---|
| 41 | """encrypt(plaintext:string|long, K:string|long) : tuple |
---|
| 42 | Encrypt the string or integer plaintext. K is a random |
---|
| 43 | parameter required by some algorithms. |
---|
| 44 | """ |
---|
| 45 | wasString=0 |
---|
| 46 | if isinstance(plaintext, types.StringType): |
---|
| 47 | plaintext=bytes_to_long(plaintext) ; wasString=1 |
---|
| 48 | if isinstance(K, types.StringType): |
---|
| 49 | K=bytes_to_long(K) |
---|
| 50 | ciphertext=self._encrypt(plaintext, K) |
---|
| 51 | if wasString: return tuple(map(long_to_bytes, ciphertext)) |
---|
| 52 | else: return ciphertext |
---|
| 53 | |
---|
| 54 | def decrypt(self, ciphertext): |
---|
| 55 | """decrypt(ciphertext:tuple|string|long): string |
---|
| 56 | Decrypt 'ciphertext' using this key. |
---|
| 57 | """ |
---|
| 58 | wasString=0 |
---|
| 59 | if not isinstance(ciphertext, types.TupleType): |
---|
| 60 | ciphertext=(ciphertext,) |
---|
| 61 | if isinstance(ciphertext[0], types.StringType): |
---|
| 62 | ciphertext=tuple(map(bytes_to_long, ciphertext)) ; wasString=1 |
---|
| 63 | plaintext=self._decrypt(ciphertext) |
---|
| 64 | if wasString: return long_to_bytes(plaintext) |
---|
| 65 | else: return plaintext |
---|
| 66 | |
---|
| 67 | def sign(self, M, K): |
---|
| 68 | """sign(M : string|long, K:string|long) : tuple |
---|
| 69 | Return a tuple containing the signature for the message M. |
---|
| 70 | K is a random parameter required by some algorithms. |
---|
| 71 | """ |
---|
| 72 | if (not self.has_private()): |
---|
| 73 | raise error, 'Private key not available in this object' |
---|
| 74 | if isinstance(M, types.StringType): M=bytes_to_long(M) |
---|
| 75 | if isinstance(K, types.StringType): K=bytes_to_long(K) |
---|
| 76 | return self._sign(M, K) |
---|
| 77 | |
---|
| 78 | def verify (self, M, signature): |
---|
| 79 | """verify(M:string|long, signature:tuple) : bool |
---|
| 80 | Verify that the signature is valid for the message M; |
---|
| 81 | returns true if the signature checks out. |
---|
| 82 | """ |
---|
| 83 | if isinstance(M, types.StringType): M=bytes_to_long(M) |
---|
| 84 | return self._verify(M, signature) |
---|
| 85 | |
---|
| 86 | # alias to compensate for the old validate() name |
---|
| 87 | def validate (self, M, signature): |
---|
| 88 | warnings.warn("validate() method name is obsolete; use verify()", |
---|
| 89 | DeprecationWarning) |
---|
| 90 | |
---|
| 91 | def blind(self, M, B): |
---|
| 92 | """blind(M : string|long, B : string|long) : string|long |
---|
| 93 | Blind message M using blinding factor B. |
---|
| 94 | """ |
---|
| 95 | wasString=0 |
---|
| 96 | if isinstance(M, types.StringType): |
---|
| 97 | M=bytes_to_long(M) ; wasString=1 |
---|
| 98 | if isinstance(B, types.StringType): B=bytes_to_long(B) |
---|
| 99 | blindedmessage=self._blind(M, B) |
---|
| 100 | if wasString: return long_to_bytes(blindedmessage) |
---|
| 101 | else: return blindedmessage |
---|
| 102 | |
---|
| 103 | def unblind(self, M, B): |
---|
| 104 | """unblind(M : string|long, B : string|long) : string|long |
---|
| 105 | Unblind message M using blinding factor B. |
---|
| 106 | """ |
---|
| 107 | wasString=0 |
---|
| 108 | if isinstance(M, types.StringType): |
---|
| 109 | M=bytes_to_long(M) ; wasString=1 |
---|
| 110 | if isinstance(B, types.StringType): B=bytes_to_long(B) |
---|
| 111 | unblindedmessage=self._unblind(M, B) |
---|
| 112 | if wasString: return long_to_bytes(unblindedmessage) |
---|
| 113 | else: return unblindedmessage |
---|
| 114 | |
---|
| 115 | |
---|
| 116 | # The following methods will usually be left alone, except for |
---|
| 117 | # signature-only algorithms. They both return Boolean values |
---|
| 118 | # recording whether this key's algorithm can sign and encrypt. |
---|
| 119 | def can_sign (self): |
---|
| 120 | """can_sign() : bool |
---|
| 121 | Return a Boolean value recording whether this algorithm can |
---|
| 122 | generate signatures. (This does not imply that this |
---|
| 123 | particular key object has the private information required to |
---|
| 124 | to generate a signature.) |
---|
| 125 | """ |
---|
| 126 | return 1 |
---|
| 127 | |
---|
| 128 | def can_encrypt (self): |
---|
| 129 | """can_encrypt() : bool |
---|
| 130 | Return a Boolean value recording whether this algorithm can |
---|
| 131 | encrypt data. (This does not imply that this |
---|
| 132 | particular key object has the private information required to |
---|
| 133 | to decrypt a message.) |
---|
| 134 | """ |
---|
| 135 | return 1 |
---|
| 136 | |
---|
| 137 | def can_blind (self): |
---|
| 138 | """can_blind() : bool |
---|
| 139 | Return a Boolean value recording whether this algorithm can |
---|
| 140 | blind data. (This does not imply that this |
---|
| 141 | particular key object has the private information required to |
---|
| 142 | to blind a message.) |
---|
| 143 | """ |
---|
| 144 | return 0 |
---|
| 145 | |
---|
| 146 | # The following methods will certainly be overridden by |
---|
| 147 | # subclasses. |
---|
| 148 | |
---|
| 149 | def size (self): |
---|
| 150 | """size() : int |
---|
| 151 | Return the maximum number of bits that can be handled by this key. |
---|
| 152 | """ |
---|
| 153 | return 0 |
---|
| 154 | |
---|
| 155 | def has_private (self): |
---|
| 156 | """has_private() : bool |
---|
| 157 | Return a Boolean denoting whether the object contains |
---|
| 158 | private components. |
---|
| 159 | """ |
---|
| 160 | return 0 |
---|
| 161 | |
---|
| 162 | def publickey (self): |
---|
| 163 | """publickey(): object |
---|
| 164 | Return a new key object containing only the public information. |
---|
| 165 | """ |
---|
| 166 | return self |
---|
| 167 | |
---|
| 168 | def __eq__ (self, other): |
---|
| 169 | """__eq__(other): 0, 1 |
---|
| 170 | Compare us to other for equality. |
---|
| 171 | """ |
---|
| 172 | return self.__getstate__() == other.__getstate__() |
---|