From c787cf73b35bd11033f48d84e072ca9ca3b7335d Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Tue, 25 Apr 2023 12:13:25 +0100 Subject: [PATCH] bignum_core.py: Add "BignumCoreShiftL()" This patch introduces automatic test input generation for `mpi_core_shift_l()` function. It also adds two utility functions in bignum_common. Signed-off-by: Minos Galanakis --- scripts/mbedtls_dev/bignum_common.py | 17 ++++++++ scripts/mbedtls_dev/bignum_core.py | 62 ++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/scripts/mbedtls_dev/bignum_common.py b/scripts/mbedtls_dev/bignum_common.py index d8ef4a84f5..20f7ff88b6 100644 --- a/scripts/mbedtls_dev/bignum_common.py +++ b/scripts/mbedtls_dev/bignum_common.py @@ -80,6 +80,23 @@ def hex_digits_for_limb(limbs: int, bits_in_limb: int) -> int: """ Retrun the hex digits need for a number of limbs. """ return 2 * (limbs * bits_in_limb // 8) +def hex_digits_max_int(val: str, bits_in_limb: int) -> int: + """ Return the first number exceeding maximum the limb space + required to store the input hex-string value. This method + weights on the input str_len rather than numerical value + and works with zero-padded inputs""" + n = ((1 << (len(val) * 4)) - 1) + l = limbs_mpi(n, bits_in_limb) + return bound_mpi_limbs(l, bits_in_limb) + +def zfill_match(reference: str, target: str) -> str: + """ Zero pad target hex-string the match the limb size of + the refference input """ + lt = len(target) + lr = len(reference) + targen_len = lr if lt < lr else lt + return "{:x}".format(int(target, 16)).zfill(targen_len) + class OperationCommon(test_data_generation.BaseTest): """Common features for bignum binary operations. diff --git a/scripts/mbedtls_dev/bignum_core.py b/scripts/mbedtls_dev/bignum_core.py index 5801caef59..2abf77ac8a 100644 --- a/scripts/mbedtls_dev/bignum_core.py +++ b/scripts/mbedtls_dev/bignum_core.py @@ -68,6 +68,68 @@ class BignumCoreShiftR(BignumCoreTarget, test_data_generation.BaseTest): for count in counts: yield cls(input_hex, descr, count).create_test_case() + +class BignumCoreShiftL(BignumCoreTarget, bignum_common.ModOperationCommon): + """Test cases for mbedtls_bignum_core_shift_l().""" + + BIT_SHIFT_VALUES = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', + '1f', '20', '21', '3f', '40', '41', '47', '48', '4f', + '50', '51', '58', '80', '81', '88'] + DATA = ["0", "1", "40", "dee5ca1a7ef10a75", "a1055eb0bb1efa1150ff", + "002e7ab0070ad57001", "020100000000000000001011121314151617", + "1946e2958a85d8863ae21f4904fcc49478412534ed53eaf321f63f2a222" + "7a3c63acbf50b6305595f90cfa8327f6db80d986fe96080bcbb5df1bdbe" + "9b74fb8dedf2bddb3f8215b54dffd66409323bcc473e45a8fe9d08e77a51" + "1698b5dad0416305db7fcf"] + arity = 1 + test_function = "mpi_core_shift_l" + test_name = "Core shift(L)" + input_style = "arch_split" + symbol = "<<" + input_values = BIT_SHIFT_VALUES + moduli = DATA + + @property + def val_n_max_limbs(self) -> int: + """ Return the limb count required to store the maximum number that can + fit in a the number of digits used by val_n """ + m = bignum_common.hex_digits_max_int(self.val_n, self.bits_in_limb) - 1 + return bignum_common.limbs_mpi(m, self.bits_in_limb) + + def arguments(self) -> List[str]: + return [bignum_common.quote_str(self.val_n), + str(self.int_a) + ] + self.result() + + def description(self) -> str: + """ Format the output as: + #{count} {hex input} ({input bits} {limbs capacity}) << {bit shift} """ + bits = "({} bits in {} limbs)".format(self.int_n.bit_length(), self.val_n_max_limbs) + return "{} #{} {} {} {} {}".format(self.test_name, + self.count, + self.val_n, + bits, + self.symbol, + self.int_a) + + def format_result(self, res: int) -> str: + # Override to match zero-pading for leading digits between the output and input. + res_str = bignum_common.zfill_match(self.val_n, "{:x}".format(res)) + return bignum_common.quote_str(res_str) + + def result(self) -> List[str]: + result = (self.int_n << self.int_a) + # Calculate if there is space for shifting to the left(leading zero limbs) + mx = bignum_common.hex_digits_max_int(self.val_n, self.bits_in_limb) + # If there are empty limbs ahead, adjust the bitmask accordingly + result = result & (self.r - 1) if mx == self.r else result & (mx - 1) + return [self.format_result(result)] + + @property + def is_valid(self) -> bool: + return True + + class BignumCoreCTLookup(BignumCoreTarget, test_data_generation.BaseTest): """Test cases for mbedtls_mpi_core_ct_uint_table_lookup().""" test_function = "mpi_core_ct_uint_table_lookup"