[utils] Add bytes_to_long() and long_to_bytes()
Used in daisuki.net (#4738) Both are adapted from public domain PyCrypto: https://github.com/dlitz/pycrypto/blob/master/lib/Crypto/Util/number.py
This commit is contained in:
		@@ -3319,6 +3319,57 @@ class PerRequestProxyHandler(compat_urllib_request.ProxyHandler):
 | 
			
		||||
            self, req, proxy, type)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Both long_to_bytes and bytes_to_long are adapted from PyCrypto, which is
 | 
			
		||||
# released into Public Domain
 | 
			
		||||
# https://github.com/dlitz/pycrypto/blob/master/lib/Crypto/Util/number.py#L387
 | 
			
		||||
 | 
			
		||||
def long_to_bytes(n, blocksize=0):
 | 
			
		||||
    """long_to_bytes(n:long, blocksize:int) : string
 | 
			
		||||
    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 = b''
 | 
			
		||||
    n = int(n)
 | 
			
		||||
    while n > 0:
 | 
			
		||||
        s = compat_struct_pack('>I', n & 0xffffffff) + s
 | 
			
		||||
        n = n >> 32
 | 
			
		||||
    # strip off leading zeros
 | 
			
		||||
    for i in range(len(s)):
 | 
			
		||||
        if s[i] != b'\000'[0]:
 | 
			
		||||
            break
 | 
			
		||||
    else:
 | 
			
		||||
        # only happens when n == 0
 | 
			
		||||
        s = b'\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) * b'\000' + s
 | 
			
		||||
    return s
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def bytes_to_long(s):
 | 
			
		||||
    """bytes_to_long(string) : long
 | 
			
		||||
    Convert a byte string to a long integer.
 | 
			
		||||
 | 
			
		||||
    This is (essentially) the inverse of long_to_bytes().
 | 
			
		||||
    """
 | 
			
		||||
    acc = 0
 | 
			
		||||
    length = len(s)
 | 
			
		||||
    if length % 4:
 | 
			
		||||
        extra = (4 - length % 4)
 | 
			
		||||
        s = b'\000' * extra + s
 | 
			
		||||
        length = length + extra
 | 
			
		||||
    for i in range(0, length, 4):
 | 
			
		||||
        acc = (acc << 32) + compat_struct_unpack('>I', s[i:i + 4])[0]
 | 
			
		||||
    return acc
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def ohdave_rsa_encrypt(data, exponent, modulus):
 | 
			
		||||
    '''
 | 
			
		||||
    Implement OHDave's RSA algorithm. See http://www.ohdave.com/rsa/
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user