Index: third_party/google-endpoints/Crypto/PublicKey/_slowmath.py |
diff --git a/third_party/google-endpoints/Crypto/PublicKey/_slowmath.py b/third_party/google-endpoints/Crypto/PublicKey/_slowmath.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..d926596e23011fde0af6e5e09f74e514f1e0f283 |
--- /dev/null |
+++ b/third_party/google-endpoints/Crypto/PublicKey/_slowmath.py |
@@ -0,0 +1,187 @@ |
+# -*- coding: utf-8 -*- |
+# |
+# PubKey/RSA/_slowmath.py : Pure Python implementation of the RSA portions of _fastmath |
+# |
+# Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net> |
+# |
+# =================================================================== |
+# The contents of this file are dedicated to the public domain. To |
+# the extent that dedication to the public domain is not available, |
+# everyone is granted a worldwide, perpetual, royalty-free, |
+# non-exclusive license to exercise all rights associated with the |
+# contents of this file for any purpose whatsoever. |
+# No rights are reserved. |
+# |
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
+# SOFTWARE. |
+# =================================================================== |
+ |
+"""Pure Python implementation of the RSA-related portions of Crypto.PublicKey._fastmath.""" |
+ |
+__revision__ = "$Id$" |
+ |
+__all__ = ['rsa_construct'] |
+ |
+import sys |
+ |
+if sys.version_info[0] == 2 and sys.version_info[1] == 1: |
+ from Crypto.Util.py21compat import * |
+from Crypto.Util.number import size, inverse, GCD |
+ |
+class error(Exception): |
+ pass |
+ |
+class _RSAKey(object): |
+ def _blind(self, m, r): |
+ # compute r**e * m (mod n) |
+ return m * pow(r, self.e, self.n) |
+ |
+ def _unblind(self, m, r): |
+ # compute m / r (mod n) |
+ return inverse(r, self.n) * m % self.n |
+ |
+ def _decrypt(self, c): |
+ # compute c**d (mod n) |
+ if not self.has_private(): |
+ raise TypeError("No private key") |
+ if (hasattr(self,'p') and hasattr(self,'q') and hasattr(self,'u')): |
+ m1 = pow(c, self.d % (self.p-1), self.p) |
+ m2 = pow(c, self.d % (self.q-1), self.q) |
+ h = m2 - m1 |
+ if (h<0): |
+ h = h + self.q |
+ h = h*self.u % self.q |
+ return h*self.p+m1 |
+ return pow(c, self.d, self.n) |
+ |
+ def _encrypt(self, m): |
+ # compute m**d (mod n) |
+ return pow(m, self.e, self.n) |
+ |
+ def _sign(self, m): # alias for _decrypt |
+ if not self.has_private(): |
+ raise TypeError("No private key") |
+ return self._decrypt(m) |
+ |
+ def _verify(self, m, sig): |
+ return self._encrypt(sig) == m |
+ |
+ def has_private(self): |
+ return hasattr(self, 'd') |
+ |
+ def size(self): |
+ """Return the maximum number of bits that can be encrypted""" |
+ return size(self.n) - 1 |
+ |
+def rsa_construct(n, e, d=None, p=None, q=None, u=None): |
+ """Construct an RSAKey object""" |
+ assert isinstance(n, long) |
+ assert isinstance(e, long) |
+ assert isinstance(d, (long, type(None))) |
+ assert isinstance(p, (long, type(None))) |
+ assert isinstance(q, (long, type(None))) |
+ assert isinstance(u, (long, type(None))) |
+ obj = _RSAKey() |
+ obj.n = n |
+ obj.e = e |
+ if d is None: |
+ return obj |
+ obj.d = d |
+ if p is not None and q is not None: |
+ obj.p = p |
+ obj.q = q |
+ else: |
+ # Compute factors p and q from the private exponent d. |
+ # We assume that n has no more than two factors. |
+ # See 8.2.2(i) in Handbook of Applied Cryptography. |
+ ktot = d*e-1 |
+ # The quantity d*e-1 is a multiple of phi(n), even, |
+ # and can be represented as t*2^s. |
+ t = ktot |
+ while t%2==0: |
+ t=divmod(t,2)[0] |
+ # Cycle through all multiplicative inverses in Zn. |
+ # The algorithm is non-deterministic, but there is a 50% chance |
+ # any candidate a leads to successful factoring. |
+ # See "Digitalized Signatures and Public Key Functions as Intractable |
+ # as Factorization", M. Rabin, 1979 |
+ spotted = 0 |
+ a = 2 |
+ while not spotted and a<100: |
+ k = t |
+ # Cycle through all values a^{t*2^i}=a^k |
+ while k<ktot: |
+ cand = pow(a,k,n) |
+ # Check if a^k is a non-trivial root of unity (mod n) |
+ if cand!=1 and cand!=(n-1) and pow(cand,2,n)==1: |
+ # We have found a number such that (cand-1)(cand+1)=0 (mod n). |
+ # Either of the terms divides n. |
+ obj.p = GCD(cand+1,n) |
+ spotted = 1 |
+ break |
+ k = k*2 |
+ # This value was not any good... let's try another! |
+ a = a+2 |
+ if not spotted: |
+ raise ValueError("Unable to compute factors p and q from exponent d.") |
+ # Found ! |
+ assert ((n % obj.p)==0) |
+ obj.q = divmod(n,obj.p)[0] |
+ if u is not None: |
+ obj.u = u |
+ else: |
+ obj.u = inverse(obj.p, obj.q) |
+ return obj |
+ |
+class _DSAKey(object): |
+ def size(self): |
+ """Return the maximum number of bits that can be encrypted""" |
+ return size(self.p) - 1 |
+ |
+ def has_private(self): |
+ return hasattr(self, 'x') |
+ |
+ def _sign(self, m, k): # alias for _decrypt |
+ # SECURITY TODO - We _should_ be computing SHA1(m), but we don't because that's the API. |
+ if not self.has_private(): |
+ raise TypeError("No private key") |
+ if not (1L < k < self.q): |
+ raise ValueError("k is not between 2 and q-1") |
+ inv_k = inverse(k, self.q) # Compute k**-1 mod q |
+ r = pow(self.g, k, self.p) % self.q # r = (g**k mod p) mod q |
+ s = (inv_k * (m + self.x * r)) % self.q |
+ return (r, s) |
+ |
+ def _verify(self, m, r, s): |
+ # SECURITY TODO - We _should_ be computing SHA1(m), but we don't because that's the API. |
+ if not (0 < r < self.q) or not (0 < s < self.q): |
+ return False |
+ w = inverse(s, self.q) |
+ u1 = (m*w) % self.q |
+ u2 = (r*w) % self.q |
+ v = (pow(self.g, u1, self.p) * pow(self.y, u2, self.p) % self.p) % self.q |
+ return v == r |
+ |
+def dsa_construct(y, g, p, q, x=None): |
+ assert isinstance(y, long) |
+ assert isinstance(g, long) |
+ assert isinstance(p, long) |
+ assert isinstance(q, long) |
+ assert isinstance(x, (long, type(None))) |
+ obj = _DSAKey() |
+ obj.y = y |
+ obj.g = g |
+ obj.p = p |
+ obj.q = q |
+ if x is not None: obj.x = x |
+ return obj |
+ |
+ |
+# vim:set ts=4 sw=4 sts=4 expandtab: |
+ |