def deflate_long(n, add_sign_padding=True): """turns a long-int into a normalized byte string (adapted from Crypto.Util.number)""" # after much testing, this algorithm was deemed to be the fastest s = bytes() n = long(n) while (n != 0) and (n != -1): s = struct.pack('>I', n & xffffffff) + s n >>= 32 # strip off leading zeros, FFs for i in enumerate(s): if (n == 0) and (i[1] != deflate_zero): break if (n == -1) and (i[1] != deflate_ff): break else: # degenerate case, n was either 0 or -1 i = (0,) if n == 0: s = zero_byte else: s = max_byte s = s[i[0]:] if add_sign_padding: if (n == 0) and (byte_ord(s[0]) >= 0x80): s = zero_byte + s if (n == -1) and (byte_ord(s[0]) < 0x80): s = max_byte + s return s
def constant_time_bytes_eq(a, b): if len(a) != len(b): return False res = 0 # noinspection PyUnresolvedReferences for i in (xrange if PY2 else range)(len(a)): res |= byte_ord(a[i]) ^ byte_ord(b[i]) return res == 0
def safe_string(s): out = b('') for c in s: i = byte_ord(c) if 32 <= i <= 127: out += byte_chr(i) else: out += b('%%%02X' % i) return out
def __call__(self): """Increament the counter and return the new value""" i = self.blocksize - 1 while i > -1: c = self.value[i] = byte_chr((byte_ord(self.value[i]) + 1) % 256) if c != zero_byte: return self.value.tostring() i -= 1 # counter reset x = deflate_long(self.overflow, add_sign_padding=False) self.value = array.array('c', zero_byte * (self.blocksize - len(x)) + x) return self.value.tostring()
def bit_length(n): try: return n.bitlength() except AttributeError: norm = deflate_long(n, False) hbyte = byte_ord(norm[0]) if hbyte == 0: return 1 bitlen = len(norm) * 8 while not (hbyte & 0x80): hbyte <<= 1 bitlen -= 1 return bitlen
def inflate_long(s, always_positive=False): """turns a normalized byte string into a long-int (adapted from Crypto.Util.number)""" out = long(0) negative = 0 if not always_positive and (len(s) > 0) and (byte_ord(s[0]) >= 0x80): negative = 1 if len(s) % 4: filler = zero_byte if negative: filler = max_byte # never convert this to ``s +=`` because this is a string, not a number # noinspection PyAugmentAssignment s = filler * (4 - len(s) % 4) + s for i in range(0, len(s), 4): out = (out << 32) + struct.unpack('>I', s[i:i+4])[0] if negative: out -= (long(1) << (8 * len(s))) return out
def format_binary_line(data): left = ' '.join(['%02X' % byte_ord(c) for c in data]) right = ''.join([('.%c..' % c)[(byte_ord(c)+63)//95] for c in data]) return '%-50s %s' % (left, right)