Index: third_party/google-endpoints/Crypto/Random/random.py |
diff --git a/third_party/google-endpoints/Crypto/Random/random.py b/third_party/google-endpoints/Crypto/Random/random.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..bef02e6511a2d3bd9197ed47c3bc345acac62f99 |
--- /dev/null |
+++ b/third_party/google-endpoints/Crypto/Random/random.py |
@@ -0,0 +1,142 @@ |
+# -*- coding: utf-8 -*- |
+# |
+# Random/random.py : Strong alternative for the standard 'random' module |
+# |
+# 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. |
+# =================================================================== |
+ |
+"""A cryptographically strong version of Python's standard "random" module.""" |
+ |
+__revision__ = "$Id$" |
+__all__ = ['StrongRandom', 'getrandbits', 'randrange', 'randint', 'choice', 'shuffle', 'sample'] |
+ |
+from Crypto import Random |
+import sys |
+if sys.version_info[0] == 2 and sys.version_info[1] == 1: |
+ from Crypto.Util.py21compat import * |
+ |
+class StrongRandom(object): |
+ def __init__(self, rng=None, randfunc=None): |
+ if randfunc is None and rng is None: |
+ self._randfunc = None |
+ elif randfunc is not None and rng is None: |
+ self._randfunc = randfunc |
+ elif randfunc is None and rng is not None: |
+ self._randfunc = rng.read |
+ else: |
+ raise ValueError("Cannot specify both 'rng' and 'randfunc'") |
+ |
+ def getrandbits(self, k): |
+ """Return a python long integer with k random bits.""" |
+ if self._randfunc is None: |
+ self._randfunc = Random.new().read |
+ mask = (1L << k) - 1 |
+ return mask & bytes_to_long(self._randfunc(ceil_div(k, 8))) |
+ |
+ def randrange(self, *args): |
+ """randrange([start,] stop[, step]): |
+ Return a randomly-selected element from range(start, stop, step).""" |
+ if len(args) == 3: |
+ (start, stop, step) = args |
+ elif len(args) == 2: |
+ (start, stop) = args |
+ step = 1 |
+ elif len(args) == 1: |
+ (stop,) = args |
+ start = 0 |
+ step = 1 |
+ else: |
+ raise TypeError("randrange expected at most 3 arguments, got %d" % (len(args),)) |
+ if (not isinstance(start, (int, long)) |
+ or not isinstance(stop, (int, long)) |
+ or not isinstance(step, (int, long))): |
+ raise TypeError("randrange requires integer arguments") |
+ if step == 0: |
+ raise ValueError("randrange step argument must not be zero") |
+ |
+ num_choices = ceil_div(stop - start, step) |
+ if num_choices < 0: |
+ num_choices = 0 |
+ if num_choices < 1: |
+ raise ValueError("empty range for randrange(%r, %r, %r)" % (start, stop, step)) |
+ |
+ # Pick a random number in the range of possible numbers |
+ r = num_choices |
+ while r >= num_choices: |
+ r = self.getrandbits(size(num_choices)) |
+ |
+ return start + (step * r) |
+ |
+ def randint(self, a, b): |
+ """Return a random integer N such that a <= N <= b.""" |
+ if not isinstance(a, (int, long)) or not isinstance(b, (int, long)): |
+ raise TypeError("randint requires integer arguments") |
+ N = self.randrange(a, b+1) |
+ assert a <= N <= b |
+ return N |
+ |
+ def choice(self, seq): |
+ """Return a random element from a (non-empty) sequence. |
+ |
+ If the seqence is empty, raises IndexError. |
+ """ |
+ if len(seq) == 0: |
+ raise IndexError("empty sequence") |
+ return seq[self.randrange(len(seq))] |
+ |
+ def shuffle(self, x): |
+ """Shuffle the sequence in place.""" |
+ # Make a (copy) of the list of objects we want to shuffle |
+ items = list(x) |
+ |
+ # Choose a random item (without replacement) until all the items have been |
+ # chosen. |
+ for i in xrange(len(x)): |
+ x[i] = items.pop(self.randrange(len(items))) |
+ |
+ def sample(self, population, k): |
+ """Return a k-length list of unique elements chosen from the population sequence.""" |
+ |
+ num_choices = len(population) |
+ if k > num_choices: |
+ raise ValueError("sample larger than population") |
+ |
+ retval = [] |
+ selected = {} # we emulate a set using a dict here |
+ for i in xrange(k): |
+ r = None |
+ while r is None or selected.has_key(r): |
+ r = self.randrange(num_choices) |
+ retval.append(population[r]) |
+ selected[r] = 1 |
+ return retval |
+ |
+_r = StrongRandom() |
+getrandbits = _r.getrandbits |
+randrange = _r.randrange |
+randint = _r.randint |
+choice = _r.choice |
+shuffle = _r.shuffle |
+sample = _r.sample |
+ |
+# These are at the bottom to avoid problems with recursive imports |
+from Crypto.Util.number import ceil_div, bytes_to_long, long_to_bytes, size |
+ |
+# vim:set ts=4 sw=4 sts=4 expandtab: |