diff options
Diffstat (limited to 'pypy/appspace/sha.py')
-rw-r--r-- | pypy/appspace/sha.py | 341 |
1 files changed, 0 insertions, 341 deletions
diff --git a/pypy/appspace/sha.py b/pypy/appspace/sha.py deleted file mode 100644 index 3738650a01..0000000000 --- a/pypy/appspace/sha.py +++ /dev/null @@ -1,341 +0,0 @@ -#!/usr/bin/env python -# -*- coding: iso-8859-1 - -"""A sample implementation of SHA-1 in pure Python. - - Framework adapted from Dinu Gherman's MD5 implementation by - J. Hallén and L. Creighton. SHA-1 implementation based directly on - the text of the NIST standard FIPS PUB 180-1. -""" - - -__date__ = '2004-11-17' -__version__ = 0.91 # Modernised by J. Hallén and L. Creighton for Pypy - - -import struct, copy - - -# ====================================================================== -# Bit-Manipulation helpers -# -# _long2bytes() was contributed by Barry Warsaw -# and is reused here with tiny modifications. -# ====================================================================== - -def _long2bytesBigEndian(n, blocksize=0): - """Convert a long integer to a byte string. - - If optional blocksize is given and greater than zero, pad the front - of the byte string with binary zeros so that the length is a multiple - of blocksize. - """ - - # After much testing, this algorithm was deemed to be the fastest. - s = '' - pack = struct.pack - while n > 0: - s = pack('>I', n & 0xffffffffL) + s - n = n >> 32 - - # Strip off leading zeros. - for i in range(len(s)): - if s[i] <> '\000': - break - else: - # Only happens when n == 0. - s = '\000' - i = 0 - - s = s[i:] - - # Add back some pad bytes. This could be done more efficiently - # w.r.t. the de-padding being done above, but sigh... - if blocksize > 0 and len(s) % blocksize: - s = (blocksize - len(s) % blocksize) * '\000' + s - - return s - - -def _bytelist2longBigEndian(list): - "Transform a list of characters into a list of longs." - - imax = len(list)/4 - hl = [0L] * imax - - j = 0 - i = 0 - while i < imax: - b0 = long(ord(list[j])) << 24 - b1 = long(ord(list[j+1])) << 16 - b2 = long(ord(list[j+2])) << 8 - b3 = long(ord(list[j+3])) - hl[i] = b0 | b1 | b2 | b3 - i = i+1 - j = j+4 - - return hl - - -def _rotateLeft(x, n): - "Rotate x (32 bit) left n bits circularly." - - return (x << n) | (x >> (32-n)) - - -# ====================================================================== -# The SHA transformation functions -# -# ====================================================================== - -def f0_19(B, C, D): - return (B & C) | ((~ B) & D) - -def f20_39(B, C, D): - return B ^ C ^ D - -def f40_59(B, C, D): - return (B & C) | (B & D) | (C & D) - -def f60_79(B, C, D): - return B ^ C ^ D - - -f = [f0_19, f20_39, f40_59, f60_79] - -# Constants to be used -K = [ - 0x5A827999L, # ( 0 <= t <= 19) - 0x6ED9EBA1L, # (20 <= t <= 39) - 0x8F1BBCDCL, # (40 <= t <= 59) - 0xCA62C1D6L # (60 <= t <= 79) - ] - -class MD5: - "An implementation of the MD5 hash function in pure Python." - - def __init__(self): - "Initialisation." - - # Initial message length in bits(!). - self.length = 0L - self.count = [0, 0] - - # Initial empty message as a sequence of bytes (8 bit characters). - self.input = [] - - # Call a separate init function, that can be used repeatedly - # to start from scratch on the same object. - self.init() - - - def init(self): - "Initialize the message-digest and set all fields to zero." - - self.length = 0L - self.input = [] - - # Initial 160 bit message digest (5 times 32 bit). - self.H0 = 0x67452301L - self.H1 = 0xEFCDAB89L - self.H2 = 0x98BADCFEL - self.H3 = 0x10325476L - self.H4 = 0xC3D2E1F0L - - def _transform(self, W): - - for t in range(16, 80): - W.append(_rotateLeft( - W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1) & 0xffffffffL) - - A = self.H0 - B = self.H1 - C = self.H2 - D = self.H3 - E = self.H4 - - """ - This loop was unrolled to gain about 10% in speed - for t in range(0, 80): - TEMP = _rotateLeft(A, 5) + f[t/20] + E + W[t] + K[t/20] - E = D - D = C - C = _rotateLeft(B, 30) & 0xffffffffL - B = A - A = TEMP & 0xffffffffL - """ - - for t in range(0, 20): - TEMP = _rotateLeft(A, 5) + ((B & C) | ((~ B) & D)) + E + W[t] + K[0] - E = D - D = C - C = _rotateLeft(B, 30) & 0xffffffffL - B = A - A = TEMP & 0xffffffffL - - for t in range(20, 40): - TEMP = _rotateLeft(A, 5) + (B ^ C ^ D) + E + W[t] + K[1] - E = D - D = C - C = _rotateLeft(B, 30) & 0xffffffffL - B = A - A = TEMP & 0xffffffffL - - for t in range(40, 60): - TEMP = _rotateLeft(A, 5) + ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2] - E = D - D = C - C = _rotateLeft(B, 30) & 0xffffffffL - B = A - A = TEMP & 0xffffffffL - - for t in range(60, 80): - TEMP = _rotateLeft(A, 5) + (B ^ C ^ D) + E + W[t] + K[3] - E = D - D = C - C = _rotateLeft(B, 30) & 0xffffffffL - B = A - A = TEMP & 0xffffffffL - - - self.H0 = (self.H0 + A) & 0xffffffffL - self.H1 = (self.H1 + B) & 0xffffffffL - self.H2 = (self.H2 + C) & 0xffffffffL - self.H3 = (self.H3 + D) & 0xffffffffL - self.H4 = (self.H4 + E) & 0xffffffffL - - - # Down from here all methods follow the Python Standard Library - # API of the sha module. - - def update(self, inBuf): - """Add to the current message. - - Update the md5 object with the string arg. Repeated calls - are equivalent to a single call with the concatenation of all - the arguments, i.e. m.update(a); m.update(b) is equivalent - to m.update(a+b). - - The hash is immediately calculated for all full blocks. The final - calculation is made in digest(). It will calculate 1-2 blocks, - depending on how much padding we have to add. This allows us to - keep an intermediate value for the hash, so that we only need to - make minimal recalculation if we call update() to add more data - to the hashed string. - """ - - leninBuf = long(len(inBuf)) - - # Compute number of bytes mod 64. - index = (self.count[1] >> 3) & 0x3FL - - # Update number of bits. - self.count[1] = self.count[1] + (leninBuf << 3) - if self.count[1] < (leninBuf << 3): - self.count[0] = self.count[0] + 1 - self.count[0] = self.count[0] + (leninBuf >> 29) - - partLen = 64 - index - - if leninBuf >= partLen: - self.input[index:] = list(inBuf[:partLen]) - self._transform(_bytelist2longBigEndian(self.input)) - i = partLen - while i + 63 < leninBuf: - self._transform(_bytelist2longBigEndian(list(inBuf[i:i+64]))) - i = i + 64 - else: - self.input = list(inBuf[i:leninBuf]) - else: - i = 0 - self.input = self.input + list(inBuf) - - - def digest(self): - """Terminate the message-digest computation and return digest. - - Return the digest of the strings passed to the update() - method so far. This is a 16-byte string which may contain - non-ASCII characters, including null bytes. - """ - - H0 = self.H0 - H1 = self.H1 - H2 = self.H2 - H3 = self.H3 - H4 = self.H4 - input = [] + self.input - count = [] + self.count - - index = (self.count[1] >> 3) & 0x3fL - - if index < 56: - padLen = 56 - index - else: - padLen = 120 - index - - padding = ['\200'] + ['\000'] * 63 - self.update(padding[:padLen]) - - # Append length (before padding). - bits = _bytelist2longBigEndian(self.input[:56]) + count - - self._transform(bits) - - # Store state in digest. - digest = _long2bytesBigEndian(self.H0, 4) + \ - _long2bytesBigEndian(self.H1, 4) + \ - _long2bytesBigEndian(self.H2, 4) + \ - _long2bytesBigEndian(self.H3, 4) + \ - _long2bytesBigEndian(self.H4, 4) - - self.H0 = H0 - self.H1 = H1 - self.H2 = H2 - self.H3 = H3 - self.H4 = H4 - self.input = input - self.count = count - - return digest - - - def hexdigest(self): - """Terminate and return digest in HEX form. - - Like digest() except the digest is returned as a string of - length 32, containing only hexadecimal digits. This may be - used to exchange the value safely in email or other non- - binary environments. - """ - return ''.join(['%02x' % ord(c) for c in self.digest()]) - - def copy(self): - """Return a clone object. - - Return a copy ('clone') of the md5 object. This can be used - to efficiently compute the digests of strings that share - a common initial substring. - """ - - return copy.deepcopy(self) - - -# ====================================================================== -# Mimic Python top-level functions from standard library API -# for consistency with the md5 module of the standard library. -# ====================================================================== - -digest_size = 16 - -def new(arg=None): - """Return a new md5 object. - - If arg is present, the method call update(arg) is made. - """ - - md5 = MD5() - if arg: - md5.update(arg) - - return md5 |