Beispiel #1
0
    def test_byte_length_correctness(self):
        numbers = [-12, 12, 1200, 120091, 123456789]
        for num in numbers:
            if num < 0:
                bit_length = len(bin(num, None)) - 1
            else:
                bit_length = len(bin(num, None))
            count = int(math.ceil(bit_length / 8.0))
            self.assertEqual(
                builtins.integer_byte_length(num), count, "Boom. for number %d, expected %d" % (num, count)
            )
            self.assertEqual(_alt_builtins.integer_byte_length_shift_counting(num), count)
            self.assertEqual(_alt_builtins.integer_byte_length_word_aligned(num), count)

        self.assertEqual(builtins.integer_byte_length(1 << 1023), 128)
        self.assertEqual(builtins.integer_byte_length((1 << 1024) - 1), 128)
        self.assertEqual(builtins.integer_byte_length(1 << 1024), 129)

        self.assertEqual(_alt_builtins.integer_byte_length_shift_counting(1 << 1023), 128)
        self.assertEqual(_alt_builtins.integer_byte_length_shift_counting((1 << 1024) - 1), 128)
        self.assertEqual(_alt_builtins.integer_byte_length_shift_counting(1 << 1024), 129)

        self.assertEqual(_alt_builtins.integer_byte_length_shift_counting(1 << 1023), 128)
        self.assertEqual(_alt_builtins.integer_byte_length_shift_counting((1 << 1024) - 1), 128)
        self.assertEqual(_alt_builtins.integer_byte_length_word_aligned(1 << 1024), 129)
Beispiel #2
0
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)
Beispiel #3
0
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)
Beispiel #4
0
  def test_byte_length_correctness(self):
    numbers = [-12, 12, 1200, 120091, 123456789]
    for num in numbers:
      if num < 0:
        bit_length = len(bin(num, None)) - 1
      else:
        bit_length = len(bin(num, None))
      count = int(math.ceil(bit_length / 8.0))
      self.assertEqual(builtins.integer_byte_length(num), count,
                       "Boom. for number %d, expected %d" % (num, count))
      self.assertEqual(_alt_builtins.integer_byte_length_shift_counting(num), count)
      self.assertEqual(_alt_builtins.integer_byte_length_word_aligned(num), count)

    self.assertEqual(builtins.integer_byte_length(1 << 1023), 128)
    self.assertEqual(builtins.integer_byte_length((1 << 1024) - 1), 128)
    self.assertEqual(builtins.integer_byte_length(1 << 1024), 129)

    self.assertEqual(_alt_builtins.integer_byte_length_shift_counting(1 << 1023), 128)
    self.assertEqual(_alt_builtins.integer_byte_length_shift_counting((1 << 1024) - 1), 128)
    self.assertEqual(_alt_builtins.integer_byte_length_shift_counting(1 << 1024), 129)

    self.assertEqual(_alt_builtins.integer_byte_length_shift_counting(1 << 1023), 128)
    self.assertEqual(_alt_builtins.integer_byte_length_shift_counting((1 << 1024) - 1), 128)
    self.assertEqual(_alt_builtins.integer_byte_length_word_aligned(1 << 1024), 129)
Beispiel #5
0
def long_to_bytearray(num):
  """
  Converts a long into a byte array.

  :param num:
      Long value
  :returns:
      Long.
  """
  bytes_count = builtins.integer_byte_length(num)
  byte_array = bytearray_create_zeros(bytes_count)
  for count in range(bytes_count - 1, -1, -1):
    byte_array[count] = int(num % 256)
    num >>= 8
  return byte_array
Beispiel #6
0
def long_to_bytearray(num):
    """
  Converts a long into a byte array.

  :param num:
      Long value
  :returns:
      Long.
  """
    bytes_count = builtins.integer_byte_length(num)
    byte_array = bytearray_create_zeros(bytes_count)
    for count in range(bytes_count - 1, -1, -1):
        byte_array[count] = int(num % 256)
        num >>= 8
    return byte_array
Beispiel #7
0
def uint_to_bytes_naive(number, block_size=0):
    """
  Naive slow and accurate implementation. Base for all our tests.

  Converts a number to a string of bytes.

  :param number: the number to convert
  :param block_size: the number of bytes to output. If the number encoded to
      bytes is less than this, the block will be zero-padded. When not given,
      the returned block is not padded.

  :raises:
      ``OverflowError`` when block_size is given and the number takes up more
      bytes than fit into the block.
  """
    if number < 0:
        raise ValueError("Negative numbers cannot be used: %d" % number)

    # Do some bounds checking
    needed_bytes = builtins.integer_byte_length(number)
    if block_size > 0:
        if needed_bytes > block_size:
            raise OverflowError("Needed %i bytes for number, but block size "
                                "is %i" % (needed_bytes, block_size))

    # Convert the number to bytes.
    if number == 0:
        raw_bytes = [ZERO_BYTE]
    else:
        raw_bytes = []
        num = number
        while num > 0:
            raw_bytes.insert(0, builtins.byte(num & 0xFF))
            num >>= 8

    # Pad with zeroes to fill the block
    if block_size > 0:
        padding_size = (block_size - needed_bytes)
        if number == 0:
            padding_size -= 1
        padding = ZERO_BYTE * padding_size
    else:
        padding = EMPTY_BYTE
    return padding + EMPTY_BYTE.join(raw_bytes)
Beispiel #8
0
def uint_to_bytes_naive(number, block_size=0):
  """
  Naive slow and accurate implementation. Base for all our tests.

  Converts a number to a string of bytes.

  :param number: the number to convert
  :param block_size: the number of bytes to output. If the number encoded to
      bytes is less than this, the block will be zero-padded. When not given,
      the returned block is not padded.

  :raises:
      ``OverflowError`` when block_size is given and the number takes up more
      bytes than fit into the block.
  """
  if number < 0:
    raise ValueError("Negative numbers cannot be used: %d" % number)

  # Do some bounds checking
  needed_bytes = builtins.integer_byte_length(number)
  if block_size > 0:
    if needed_bytes > block_size:
      raise OverflowError("Needed %i bytes for number, but block size "
                          "is %i" % (needed_bytes, block_size))

  # Convert the number to bytes.
  if number == 0:
    raw_bytes = [ZERO_BYTE]
  else:
    raw_bytes = []
    num = number
    while num > 0:
      raw_bytes.insert(0, builtins.byte(num & 0xFF))
      num >>= 8

  # Pad with zeroes to fill the block
  if block_size > 0:
    padding_size = (block_size - needed_bytes)
    if number == 0:
      padding_size -= 1
    padding = ZERO_BYTE * padding_size
  else:
    padding = EMPTY_BYTE
  return padding + EMPTY_BYTE.join(raw_bytes)
Beispiel #9
0
def uint_to_bytes_naive_array_based(uint, chunk_size=0):
  """
  Converts an integer into bytes.

  :param uint:
      Unsigned integer value.
  :param chunk_size:
      Chunk size.
  :returns:
      Bytes.
  """
  if uint < 0:
    raise ValueError('Negative numbers cannot be used: %i' % uint)
  if uint == 0:
    bytes_count = 1
  else:
    bytes_count = integer_byte_length(uint)
  byte_array = array('B', [0] * bytes_count)
  for count in range(bytes_count - 1, -1, -1):
    byte_array[count] = uint & 0xff
    uint >>= 8
  raw_bytes = byte_array.tostring()

  if chunk_size > 0:
    # Bounds checking. We're not doing this up-front because the
    # most common use case is not specifying a chunk size. In the worst
    # case, the number will already have been converted to bytes above.
    length = len(raw_bytes)
    bytes_needed = bytes_count
    if bytes_needed > chunk_size:
      raise OverflowError(
        "Need %d bytes for number, but chunk size is %d" %
        (bytes_needed, chunk_size)
      )
    remainder = length % chunk_size
    if remainder:
      raw_bytes = (chunk_size - remainder) * ZERO_BYTE + raw_bytes
  return raw_bytes
Beispiel #10
0
def uint_to_bytes_naive_array_based(uint, chunk_size=0):
    """
  Converts an integer into bytes.

  :param uint:
      Unsigned integer value.
  :param chunk_size:
      Chunk size.
  :returns:
      Bytes.
  """
    if uint < 0:
        raise ValueError("Negative numbers cannot be used: %i" % uint)
    if uint == 0:
        bytes_count = 1
    else:
        bytes_count = builtins.integer_byte_length(uint)
    byte_array = array.array("B", [0] * bytes_count)
    for count in builtins.range(bytes_count - 1, -1, -1):
        byte_array[count] = uint & 0xff
        uint >>= 8
    raw_bytes = byte_array.tostring()

    if chunk_size > 0:
        # Bounds checking. We're not doing this up-front because the
        # most common use case is not specifying a chunk size. In the worst
        # case, the number will already have been converted to bytes above.
        length = len(raw_bytes)
        bytes_needed = bytes_count
        if bytes_needed > chunk_size:
            raise OverflowError(
                "Need %d bytes for number, but chunk size is %d" %
                (bytes_needed, chunk_size))
        remainder = length % chunk_size
        if remainder:
            raw_bytes = (chunk_size - remainder) * ZERO_BYTE + raw_bytes
    return raw_bytes
Beispiel #11
0
 def test_byte_length_zero_if_zero(self):
   self.assertEqual(builtins.integer_byte_length(0), 0)
   self.assertEqual(_alt_builtins.integer_byte_length_shift_counting(0), 0)
   self.assertEqual(_alt_builtins.integer_byte_length_word_aligned(0), 0)
Beispiel #12
0
 def test_byte_length_zero_if_zero(self):
   self.assertEqual(integer_byte_length(0), 0)
   self.assertEqual(integer_byte_length_shift_counting(0), 0)
   self.assertEqual(integer_byte_length_word_aligned(0), 0)