def long_to_mpi(num): """ Converts a long value into an OpenSSL-format MPI Bignum byte string. :param num: Long value. :returns: OpenSSL-format MPI Bignum byte string. """ # from mom._types.bytearray import \ # long_to_bytearray, bytearray_concat, \ # bytearray_to_bytes, bytearray_create_zeros byte_array = long_to_bytearray(num) ext = 0 # If the high-order bit is going to be set, # add an extra byte of zeros if not (builtins.integer_bit_length(num) & 0x7): ext = 1 length = builtins.integer_byte_length(num) + ext byte_array = bytearray_concat(bytearray_create_zeros(4 + ext), byte_array) byte_array[0] = (length >> 24) & 0xFF byte_array[1] = (length >> 16) & 0xFF byte_array[2] = (length >> 8) & 0xFF byte_array[3] = length & 0xFF return bytearray_to_bytes(byte_array)
def test_bit_length_correct(self): numbers = [ -12, 12, 1200, 120091, 123456789, ] for num in numbers: if num < 0: length = len(bin(num, None)) - 1 else: length = len(bin(num, None)) self.assertEqual(builtins.integer_bit_length(num), length) self.assertEqual(_alt_builtins.integer_bit_length_shift_counting(num), length) self.assertEqual(_alt_builtins.integer_bit_length_word_aligned(num), length) self.assertEqual(builtins.integer_bit_length(1023), 10) self.assertEqual(builtins.integer_bit_length(1024), 11) self.assertEqual(builtins.integer_bit_length(1025), 11) self.assertEqual(builtins.integer_bit_length(1 << 1024), 1025) self.assertEqual(builtins.integer_bit_length((1 << 1024) + 1), 1025) self.assertEqual(builtins.integer_bit_length((1 << 1024) - 1), 1024) self.assertEqual(builtins.integer_bit_length((1 << 32) - 1), 32) self.assertEqual(builtins.integer_bit_length((1 << 64) - 1), 64) self.assertEqual(_alt_builtins.integer_bit_length_shift_counting(1023), 10) self.assertEqual(_alt_builtins.integer_bit_length_shift_counting(1024), 11) self.assertEqual(_alt_builtins.integer_bit_length_shift_counting(1025), 11) self.assertEqual(_alt_builtins.integer_bit_length_shift_counting(1 << 1024), 1025) self.assertEqual(_alt_builtins.integer_bit_length_shift_counting((1 << 1024) + 1), 1025) self.assertEqual(_alt_builtins.integer_bit_length_shift_counting((1 << 1024) - 1), 1024) self.assertEqual(_alt_builtins.integer_bit_length_shift_counting((1 << 32) - 1), 32) self.assertEqual(_alt_builtins.integer_bit_length_shift_counting((1 << 64) - 1), 64) self.assertEqual(_alt_builtins.integer_bit_length_word_aligned(1023), 10) self.assertEqual(_alt_builtins.integer_bit_length_word_aligned(1024), 11) self.assertEqual(_alt_builtins.integer_bit_length_word_aligned(1025), 11) self.assertEqual(_alt_builtins.integer_bit_length_word_aligned(1 << 1024), 1025) self.assertEqual(_alt_builtins.integer_bit_length_word_aligned((1 << 1024) + 1), 1025) self.assertEqual(_alt_builtins.integer_bit_length_word_aligned((1 << 1024) - 1), 1024) self.assertEqual(_alt_builtins.integer_bit_length_word_aligned((1 << 32) - 1), 32) self.assertEqual(_alt_builtins.integer_bit_length_word_aligned((1 << 64) - 1), 64)
def test_bit_length_correct(self): numbers = [ -12, 12, 1200, 120091, 123456789, ] for num in numbers: if num < 0: length = len(bin(num, None)) - 1 else: length = len(bin(num, None)) self.assertEqual(integer_bit_length(num), length) self.assertEqual(integer_bit_length_shift_counting(num), length) self.assertEqual(integer_bit_length_word_aligned(num), length) self.assertEqual(integer_bit_length(1023), 10) self.assertEqual(integer_bit_length(1024), 11) self.assertEqual(integer_bit_length(1025), 11) self.assertEqual(integer_bit_length(1 << 1024), 1025) self.assertEqual(integer_bit_length((1 << 1024) + 1), 1025) self.assertEqual(integer_bit_length((1 << 1024) - 1), 1024) self.assertEqual(integer_bit_length((1 << 32) - 1), 32) self.assertEqual(integer_bit_length((1 << 64) - 1), 64) self.assertEqual(integer_bit_length_shift_counting(1023), 10) self.assertEqual(integer_bit_length_shift_counting(1024), 11) self.assertEqual(integer_bit_length_shift_counting(1025), 11) self.assertEqual(integer_bit_length_shift_counting(1 << 1024), 1025) self.assertEqual(integer_bit_length_shift_counting((1 << 1024) + 1), 1025) self.assertEqual(integer_bit_length_shift_counting((1 << 1024) - 1), 1024) self.assertEqual(integer_bit_length_shift_counting((1 << 32) - 1), 32) self.assertEqual(integer_bit_length_shift_counting((1 << 64) - 1), 64) self.assertEqual(integer_bit_length_word_aligned(1023), 10) self.assertEqual(integer_bit_length_word_aligned(1024), 11) self.assertEqual(integer_bit_length_word_aligned(1025), 11) self.assertEqual(integer_bit_length_word_aligned(1 << 1024), 1025) self.assertEqual(integer_bit_length_word_aligned((1 << 1024) + 1), 1025) self.assertEqual(integer_bit_length_word_aligned((1 << 1024) - 1), 1024) self.assertEqual(integer_bit_length_word_aligned((1 << 32) - 1), 32) self.assertEqual(integer_bit_length_word_aligned((1 << 64) - 1), 64)
def generate_random_uint_between(low, high, rand_func=generate_random_bytes): """ Generates a random long integer between low and high, not including high. :param low: Low :param high: High :param rand_func: Random bytes generator function. :returns: Random unsigned long integer value. """ # if not (is_integer(low) and is_integer(high)): # raise TypeError("unsupported operand types(s): %r and %r" \ # % (type(low).__name__, type(high).__name__)) if low >= high: raise ValueError("high value must be greater than low value.") r = high - low - 1 bits = integer_bit_length(r) value = generate_random_uint_atmost(bits, rand_func=rand_func) while value > r: value = generate_random_uint_atmost(bits, rand_func=rand_func) return low + value
def test_bit_length_0_if_zero(self): self.assertEqual(builtins.integer_bit_length(0), 0) self.assertEqual(_alt_builtins.integer_bit_length_shift_counting(0), 0) self.assertEqual(_alt_builtins.integer_bit_length_word_aligned(0), 0)
def test_bit_length_0_if_zero(self): self.assertEqual(integer_bit_length(0), 0) self.assertEqual(integer_bit_length_shift_counting(0), 0) self.assertEqual(integer_bit_length_word_aligned(0), 0)