diff --git a/scripts/mbedtls_dev/test_generation.py b/scripts/mbedtls_dev/test_generation.py new file mode 100644 index 000000000000..5de0b885c8a6 --- /dev/null +++ b/scripts/mbedtls_dev/test_generation.py @@ -0,0 +1,204 @@ +"""Common test generation classes and main function. + +These are used both by generate_psa_tests.py and generate_bignum_tests.py. +""" + +# Copyright The Mbed TLS Contributors +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import argparse +import os +import posixpath +import re + +from abc import ABCMeta, abstractmethod +from typing import Callable, Dict, Iterable, Iterator, List, Type, TypeVar + +from mbedtls_dev import test_case + +T = TypeVar('T') #pylint: disable=invalid-name + + +class BaseTarget(metaclass=ABCMeta): + """Base target for test case generation. + + Child classes of this class represent an output file, and can be referred + to as file targets. These indicate where test cases will be written to for + all subclasses of the file target, which is set by `target_basename`. + + Attributes: + count: Counter for test cases from this class. + case_description: Short description of the test case. This may be + automatically generated using the class, or manually set. + dependencies: A list of dependencies required for the test case. + show_test_count: Toggle for inclusion of `count` in the test description. + target_basename: Basename of file to write generated tests to. This + should be specified in a child class of BaseTarget. + test_function: Test function which the class generates cases for. + test_name: A common name or description of the test function. This can + be `test_function`, a clearer equivalent, or a short summary of the + test function's purpose. + """ + count = 0 + case_description = "" + dependencies = [] # type: List[str] + show_test_count = True + target_basename = "" + test_function = "" + test_name = "" + + def __new__(cls, *args, **kwargs): + # pylint: disable=unused-argument + cls.count += 1 + return super().__new__(cls) + + @abstractmethod + def arguments(self) -> List[str]: + """Get the list of arguments for the test case. + + Override this method to provide the list of arguments required for + the `test_function`. + + Returns: + List of arguments required for the test function. + """ + raise NotImplementedError + + def description(self) -> str: + """Create a test case description. + + Creates a description of the test case, including a name for the test + function, an optional case count, and a description of the specific + test case. This should inform a reader what is being tested, and + provide context for the test case. + + Returns: + Description for the test case. + """ + if self.show_test_count: + return "{} #{} {}".format( + self.test_name, self.count, self.case_description + ).strip() + else: + return "{} {}".format(self.test_name, self.case_description).strip() + + + def create_test_case(self) -> test_case.TestCase: + """Generate TestCase from the instance.""" + tc = test_case.TestCase() + tc.set_description(self.description()) + tc.set_function(self.test_function) + tc.set_arguments(self.arguments()) + tc.set_dependencies(self.dependencies) + + return tc + + @classmethod + @abstractmethod + def generate_function_tests(cls) -> Iterator[test_case.TestCase]: + """Generate test cases for the class test function. + + This will be called in classes where `test_function` is set. + Implementations should yield TestCase objects, by creating instances + of the class with appropriate input data, and then calling + `create_test_case()` on each. + """ + raise NotImplementedError + + @classmethod + def generate_tests(cls) -> Iterator[test_case.TestCase]: + """Generate test cases for the class and its subclasses. + + In classes with `test_function` set, `generate_function_tests()` is + called to generate test cases first. + + In all classes, this method will iterate over its subclasses, and + yield from `generate_tests()` in each. Calling this method on a class X + will yield test cases from all classes derived from X. + """ + if cls.test_function: + yield from cls.generate_function_tests() + for subclass in sorted(cls.__subclasses__(), key=lambda c: c.__name__): + yield from subclass.generate_tests() + + +class TestGenerator: + """Generate test cases and write to data files.""" + def __init__(self, options) -> None: + self.test_suite_directory = self.get_option(options, 'directory', + 'tests/suites') + # Update `targets` with an entry for each child class of BaseTarget. + # Each entry represents a file generated by the BaseTarget framework, + # and enables generating the .data files using the CLI. + self.targets.update({ + subclass.target_basename: subclass.generate_tests + for subclass in BaseTarget.__subclasses__() + }) + + @staticmethod + def get_option(options, name: str, default: T) -> T: + value = getattr(options, name, None) + return default if value is None else value + + def filename_for(self, basename: str) -> str: + """The location of the data file with the specified base name.""" + return posixpath.join(self.test_suite_directory, basename + '.data') + + def write_test_data_file(self, basename: str, + test_cases: Iterable[test_case.TestCase]) -> None: + """Write the test cases to a .data file. + + The output file is ``basename + '.data'`` in the test suite directory. + """ + filename = self.filename_for(basename) + test_case.write_data_file(filename, test_cases) + + # Note that targets whose names contain 'test_format' have their content + # validated by `abi_check.py`. + targets = {} # type: Dict[str, Callable[..., Iterable[test_case.TestCase]]] + + def generate_target(self, name: str, *target_args) -> None: + """Generate cases and write to data file for a target. + + For target callables which require arguments, override this function + and pass these arguments using super() (see PSATestGenerator). + """ + test_cases = self.targets[name](*target_args) + self.write_test_data_file(name, test_cases) + +def main(args, description: str, generator_class: Type[TestGenerator] = TestGenerator): + """Command line entry point.""" + parser = argparse.ArgumentParser(description=description) + parser.add_argument('--list', action='store_true', + help='List available targets and exit') + parser.add_argument('targets', nargs='*', metavar='TARGET', + help='Target file to generate (default: all; "-": none)') + options = parser.parse_args(args) + generator = generator_class(options) + if options.list: + for name in sorted(generator.targets): + print(generator.filename_for(name)) + return + if options.targets: + # Allow "-" as a special case so you can run + # ``generate_xxx_tests.py - $targets`` and it works uniformly whether + # ``$targets`` is empty or not. + options.targets = [os.path.basename(re.sub(r'\.data\Z', r'', target)) + for target in options.targets + if target != '-'] + else: + options.targets = sorted(generator.targets) + for target in options.targets: + generator.generate_target(target) diff --git a/tests/scripts/check-generated-files.sh b/tests/scripts/check-generated-files.sh index 75730ba25483..3e5cb86c9890 100755 --- a/tests/scripts/check-generated-files.sh +++ b/tests/scripts/check-generated-files.sh @@ -107,4 +107,5 @@ check scripts/generate_query_config.pl programs/test/query_config.c check scripts/generate_features.pl library/version_features.c check scripts/generate_visualc_files.pl visualc/VS2010 check scripts/generate_psa_constants.py programs/psa/psa_constant_names_generated.c +check tests/scripts/generate_bignum_tests.py $(tests/scripts/generate_bignum_tests.py --list) check tests/scripts/generate_psa_tests.py $(tests/scripts/generate_psa_tests.py --list) diff --git a/tests/scripts/generate_bignum_tests.py b/tests/scripts/generate_bignum_tests.py new file mode 100755 index 000000000000..ceafa4a489e6 --- /dev/null +++ b/tests/scripts/generate_bignum_tests.py @@ -0,0 +1,238 @@ +#!/usr/bin/env python3 +"""Generate test data for bignum functions. + +With no arguments, generate all test data. With non-option arguments, +generate only the specified files. + +Class structure: + +Child classes of test_generation.BaseTarget (file targets) represent an output +file. These indicate where test cases will be written to, for all subclasses of +this target. Multiple file targets should not reuse a `target_basename`. + +Each subclass derived from a file target can either be: + - A concrete class, representing a test function, which generates test cases. + - An abstract class containing shared methods and attributes, not associated + with a test function. An example is BignumOperation, which provides + common features used for bignum binary operations. + +Both concrete and abstract subclasses can be derived from, to implement +additional test cases (see BignumCmp and BignumCmpAbs for examples of deriving +from abstract and concrete classes). + + +Adding test case generation for a function: + +A subclass representing the test function should be added, deriving from a +file target such as BignumTarget. This test class must set/implement the +following: + - test_function: the function name from the associated .function file. + - test_name: a descriptive name or brief summary to refer to the test + function. + - arguments(): a method to generate the list of arguments required for the + test_function. + - generate_function_test(): a method to generate TestCases for the function. + This should create instances of the class with required input data, and + call `.create_test_case()` to yield the TestCase. + +Additional details and other attributes/methods are given in the documentation +of BaseTarget in test_generation.py. +""" + +# Copyright The Mbed TLS Contributors +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import itertools +import sys +import typing + +from abc import ABCMeta, abstractmethod +from typing import Iterator, List, Tuple, TypeVar + +import scripts_path # pylint: disable=unused-import +from mbedtls_dev import test_case +from mbedtls_dev import test_generation + +T = TypeVar('T') #pylint: disable=invalid-name + +def hex_to_int(val: str) -> int: + return int(val, 16) if val else 0 + +def quote_str(val) -> str: + return "\"{}\"".format(val) + +def combination_pairs(values: List[T]) -> List[Tuple[T, T]]: + """Return all pair combinations from input values. + + The return value is cast, as older versions of mypy are unable to derive + the specific type returned by itertools.combinations_with_replacement. + """ + return typing.cast( + List[Tuple[T, T]], + list(itertools.combinations_with_replacement(values, 2)) + ) + + +class BignumTarget(test_generation.BaseTarget, metaclass=ABCMeta): + #pylint: disable=abstract-method + """Target for bignum (mpi) test case generation.""" + target_basename = 'test_suite_mpi.generated' + + +class BignumOperation(BignumTarget, metaclass=ABCMeta): + """Common features for bignum binary operations. + + This adds functionality common in binary operation tests. This includes + generation of case descriptions, using descriptions of values and symbols + to represent the operation or result. + + Attributes: + symbol: Symbol used for the operation in case description. + input_values: List of values to use as test case inputs. These are + combined to produce pairs of values. + input_cases: List of tuples containing pairs of test case inputs. This + can be used to implement specific pairs of inputs. + """ + symbol = "" + input_values = [ + "", "0", "7b", "-7b", + "0000000000000000123", "-0000000000000000123", + "1230000000000000000", "-1230000000000000000" + ] # type: List[str] + input_cases = [] # type: List[Tuple[str, str]] + + def __init__(self, val_a: str, val_b: str) -> None: + self.arg_a = val_a + self.arg_b = val_b + self.int_a = hex_to_int(val_a) + self.int_b = hex_to_int(val_b) + + def arguments(self) -> List[str]: + return [quote_str(self.arg_a), quote_str(self.arg_b), self.result()] + + def description(self) -> str: + """Generate a description for the test case. + + If not set, case_description uses the form A `symbol` B, where symbol + is used to represent the operation. Descriptions of each value are + generated to provide some context to the test case. + """ + if not self.case_description: + self.case_description = "{} {} {}".format( + self.value_description(self.arg_a), + self.symbol, + self.value_description(self.arg_b) + ) + return super().description() + + @abstractmethod + def result(self) -> str: + """Get the result of the operation. + + This could be calculated during initialization and stored as `_result` + and then returned, or calculated when the method is called. + """ + raise NotImplementedError + + @staticmethod + def value_description(val) -> str: + """Generate a description of the argument val. + + This produces a simple description of the value, which is used in test + case naming to add context. + """ + if val == "": + return "0 (null)" + if val == "0": + return "0 (1 limb)" + + if val[0] == "-": + tmp = "negative" + val = val[1:] + else: + tmp = "positive" + if val[0] == "0": + tmp += " with leading zero limb" + elif len(val) > 10: + tmp = "large " + tmp + return tmp + + @classmethod + def get_value_pairs(cls) -> Iterator[Tuple[str, str]]: + """Generator to yield pairs of inputs. + + Combinations are first generated from all input values, and then + specific cases provided. + """ + yield from combination_pairs(cls.input_values) + yield from cls.input_cases + + @classmethod + def generate_function_tests(cls) -> Iterator[test_case.TestCase]: + for a_value, b_value in cls.get_value_pairs(): + cur_op = cls(a_value, b_value) + yield cur_op.create_test_case() + + +class BignumCmp(BignumOperation): + """Test cases for bignum value comparison.""" + count = 0 + test_function = "mbedtls_mpi_cmp_mpi" + test_name = "MPI compare" + input_cases = [ + ("-2", "-3"), + ("-2", "-2"), + ("2b4", "2b5"), + ("2b5", "2b6") + ] + + def __init__(self, val_a, val_b) -> None: + super().__init__(val_a, val_b) + self._result = int(self.int_a > self.int_b) - int(self.int_a < self.int_b) + self.symbol = ["<", "==", ">"][self._result + 1] + + def result(self) -> str: + return str(self._result) + + +class BignumCmpAbs(BignumCmp): + """Test cases for absolute bignum value comparison.""" + count = 0 + test_function = "mbedtls_mpi_cmp_abs" + test_name = "MPI compare (abs)" + + def __init__(self, val_a, val_b) -> None: + super().__init__(val_a.strip("-"), val_b.strip("-")) + + +class BignumAdd(BignumOperation): + """Test cases for bignum value addition.""" + count = 0 + symbol = "+" + test_function = "mbedtls_mpi_add_mpi" + test_name = "MPI add" + input_cases = combination_pairs( + [ + "1c67967269c6", "9cde3", + "-1c67967269c6", "-9cde3", + ] + ) + + def result(self) -> str: + return quote_str("{:x}".format(self.int_a + self.int_b)) + +if __name__ == '__main__': + # Use the section of the docstring relevant to the CLI as description + test_generation.main(sys.argv[1:], "\n".join(__doc__.splitlines()[:4])) diff --git a/tests/scripts/generate_psa_tests.py b/tests/scripts/generate_psa_tests.py index 33c1fc3d1c99..867a6b459453 100755 --- a/tests/scripts/generate_psa_tests.py +++ b/tests/scripts/generate_psa_tests.py @@ -20,20 +20,17 @@ # See the License for the specific language governing permissions and # limitations under the License. -import argparse import enum -import os import re import sys -from typing import Callable, Dict, FrozenSet, Iterable, Iterator, List, Optional, TypeVar +from typing import Callable, Dict, FrozenSet, Iterable, Iterator, List, Optional import scripts_path # pylint: disable=unused-import from mbedtls_dev import crypto_knowledge from mbedtls_dev import macro_collector from mbedtls_dev import psa_storage from mbedtls_dev import test_case - -T = TypeVar('T') #pylint: disable=invalid-name +from mbedtls_dev import test_generation def psa_want_symbol(name: str) -> str: @@ -897,35 +894,11 @@ def generate_all_keys(self) -> Iterator[StorageTestData]: yield from super().generate_all_keys() yield from self.all_keys_for_implicit_usage() -class TestGenerator: - """Generate test data.""" - - def __init__(self, options) -> None: - self.test_suite_directory = self.get_option(options, 'directory', - 'tests/suites') - self.info = Information() - - @staticmethod - def get_option(options, name: str, default: T) -> T: - value = getattr(options, name, None) - return default if value is None else value - - def filename_for(self, basename: str) -> str: - """The location of the data file with the specified base name.""" - return os.path.join(self.test_suite_directory, basename + '.data') - - def write_test_data_file(self, basename: str, - test_cases: Iterable[test_case.TestCase]) -> None: - """Write the test cases to a .data file. - - The output file is ``basename + '.data'`` in the test suite directory. - """ - filename = self.filename_for(basename) - test_case.write_data_file(filename, test_cases) - +class PSATestGenerator(test_generation.TestGenerator): + """Test generator subclass including PSA targets and info.""" # Note that targets whose names contain 'test_format' have their content # validated by `abi_check.py`. - TARGETS = { + targets = { 'test_suite_psa_crypto_generate_key.generated': lambda info: KeyGenerate(info).test_cases_for_key_generation(), 'test_suite_psa_crypto_not_supported.generated': @@ -938,34 +911,12 @@ def write_test_data_file(self, basename: str, lambda info: StorageFormatV0(info).all_test_cases(), } #type: Dict[str, Callable[[Information], Iterable[test_case.TestCase]]] - def generate_target(self, name: str) -> None: - test_cases = self.TARGETS[name](self.info) - self.write_test_data_file(name, test_cases) - -def main(args): - """Command line entry point.""" - parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument('--list', action='store_true', - help='List available targets and exit') - parser.add_argument('targets', nargs='*', metavar='TARGET', - help='Target file to generate (default: all; "-": none)') - options = parser.parse_args(args) - generator = TestGenerator(options) - if options.list: - for name in sorted(generator.TARGETS): - print(generator.filename_for(name)) - return - if options.targets: - # Allow "-" as a special case so you can run - # ``generate_psa_tests.py - $targets`` and it works uniformly whether - # ``$targets`` is empty or not. - options.targets = [os.path.basename(re.sub(r'\.data\Z', r'', target)) - for target in options.targets - if target != '-'] - else: - options.targets = sorted(generator.TARGETS) - for target in options.targets: - generator.generate_target(target) + def __init__(self, options): + super().__init__(options) + self.info = Information() + + def generate_target(self, name: str, *target_args) -> None: + super().generate_target(name, self.info) if __name__ == '__main__': - main(sys.argv[1:]) + test_generation.main(sys.argv[1:], __doc__, PSATestGenerator) diff --git a/tests/suites/test_suite_mpi.generated.data b/tests/suites/test_suite_mpi.generated.data new file mode 100644 index 000000000000..947d06f7fb41 --- /dev/null +++ b/tests/suites/test_suite_mpi.generated.data @@ -0,0 +1,381 @@ +# Automatically generated by generate_bignum_tests.py. Do not edit! + +MPI add #1 0 (null) + 0 (null) +mbedtls_mpi_add_mpi:"":"":"0" + +MPI add #2 0 (null) + 0 (1 limb) +mbedtls_mpi_add_mpi:"":"0":"0" + +MPI add #3 0 (null) + positive +mbedtls_mpi_add_mpi:"":"7b":"7b" + +MPI add #4 0 (null) + negative +mbedtls_mpi_add_mpi:"":"-7b":"-7b" + +MPI add #5 0 (null) + positive with leading zero limb +mbedtls_mpi_add_mpi:"":"0000000000000000123":"123" + +MPI add #6 0 (null) + negative with leading zero limb +mbedtls_mpi_add_mpi:"":"-0000000000000000123":"-123" + +MPI add #7 0 (null) + large positive +mbedtls_mpi_add_mpi:"":"1230000000000000000":"1230000000000000000" + +MPI add #8 0 (null) + large negative +mbedtls_mpi_add_mpi:"":"-1230000000000000000":"-1230000000000000000" + +MPI add #9 0 (1 limb) + 0 (1 limb) +mbedtls_mpi_add_mpi:"0":"0":"0" + +MPI add #10 0 (1 limb) + positive +mbedtls_mpi_add_mpi:"0":"7b":"7b" + +MPI add #11 0 (1 limb) + negative +mbedtls_mpi_add_mpi:"0":"-7b":"-7b" + +MPI add #12 0 (1 limb) + positive with leading zero limb +mbedtls_mpi_add_mpi:"0":"0000000000000000123":"123" + +MPI add #13 0 (1 limb) + negative with leading zero limb +mbedtls_mpi_add_mpi:"0":"-0000000000000000123":"-123" + +MPI add #14 0 (1 limb) + large positive +mbedtls_mpi_add_mpi:"0":"1230000000000000000":"1230000000000000000" + +MPI add #15 0 (1 limb) + large negative +mbedtls_mpi_add_mpi:"0":"-1230000000000000000":"-1230000000000000000" + +MPI add #16 positive + positive +mbedtls_mpi_add_mpi:"7b":"7b":"f6" + +MPI add #17 positive + negative +mbedtls_mpi_add_mpi:"7b":"-7b":"0" + +MPI add #18 positive + positive with leading zero limb +mbedtls_mpi_add_mpi:"7b":"0000000000000000123":"19e" + +MPI add #19 positive + negative with leading zero limb +mbedtls_mpi_add_mpi:"7b":"-0000000000000000123":"-a8" + +MPI add #20 positive + large positive +mbedtls_mpi_add_mpi:"7b":"1230000000000000000":"123000000000000007b" + +MPI add #21 positive + large negative +mbedtls_mpi_add_mpi:"7b":"-1230000000000000000":"-122ffffffffffffff85" + +MPI add #22 negative + negative +mbedtls_mpi_add_mpi:"-7b":"-7b":"-f6" + +MPI add #23 negative + positive with leading zero limb +mbedtls_mpi_add_mpi:"-7b":"0000000000000000123":"a8" + +MPI add #24 negative + negative with leading zero limb +mbedtls_mpi_add_mpi:"-7b":"-0000000000000000123":"-19e" + +MPI add #25 negative + large positive +mbedtls_mpi_add_mpi:"-7b":"1230000000000000000":"122ffffffffffffff85" + +MPI add #26 negative + large negative +mbedtls_mpi_add_mpi:"-7b":"-1230000000000000000":"-123000000000000007b" + +MPI add #27 positive with leading zero limb + positive with leading zero limb +mbedtls_mpi_add_mpi:"0000000000000000123":"0000000000000000123":"246" + +MPI add #28 positive with leading zero limb + negative with leading zero limb +mbedtls_mpi_add_mpi:"0000000000000000123":"-0000000000000000123":"0" + +MPI add #29 positive with leading zero limb + large positive +mbedtls_mpi_add_mpi:"0000000000000000123":"1230000000000000000":"1230000000000000123" + +MPI add #30 positive with leading zero limb + large negative +mbedtls_mpi_add_mpi:"0000000000000000123":"-1230000000000000000":"-122fffffffffffffedd" + +MPI add #31 negative with leading zero limb + negative with leading zero limb +mbedtls_mpi_add_mpi:"-0000000000000000123":"-0000000000000000123":"-246" + +MPI add #32 negative with leading zero limb + large positive +mbedtls_mpi_add_mpi:"-0000000000000000123":"1230000000000000000":"122fffffffffffffedd" + +MPI add #33 negative with leading zero limb + large negative +mbedtls_mpi_add_mpi:"-0000000000000000123":"-1230000000000000000":"-1230000000000000123" + +MPI add #34 large positive + large positive +mbedtls_mpi_add_mpi:"1230000000000000000":"1230000000000000000":"2460000000000000000" + +MPI add #35 large positive + large negative +mbedtls_mpi_add_mpi:"1230000000000000000":"-1230000000000000000":"0" + +MPI add #36 large negative + large negative +mbedtls_mpi_add_mpi:"-1230000000000000000":"-1230000000000000000":"-2460000000000000000" + +MPI add #37 large positive + large positive +mbedtls_mpi_add_mpi:"1c67967269c6":"1c67967269c6":"38cf2ce4d38c" + +MPI add #38 large positive + positive +mbedtls_mpi_add_mpi:"1c67967269c6":"9cde3":"1c67967c37a9" + +MPI add #39 large positive + large negative +mbedtls_mpi_add_mpi:"1c67967269c6":"-1c67967269c6":"0" + +MPI add #40 large positive + negative +mbedtls_mpi_add_mpi:"1c67967269c6":"-9cde3":"1c6796689be3" + +MPI add #41 positive + positive +mbedtls_mpi_add_mpi:"9cde3":"9cde3":"139bc6" + +MPI add #42 positive + large negative +mbedtls_mpi_add_mpi:"9cde3":"-1c67967269c6":"-1c6796689be3" + +MPI add #43 positive + negative +mbedtls_mpi_add_mpi:"9cde3":"-9cde3":"0" + +MPI add #44 large negative + large negative +mbedtls_mpi_add_mpi:"-1c67967269c6":"-1c67967269c6":"-38cf2ce4d38c" + +MPI add #45 large negative + negative +mbedtls_mpi_add_mpi:"-1c67967269c6":"-9cde3":"-1c67967c37a9" + +MPI add #46 negative + negative +mbedtls_mpi_add_mpi:"-9cde3":"-9cde3":"-139bc6" + +MPI compare #1 0 (null) == 0 (null) +mbedtls_mpi_cmp_mpi:"":"":0 + +MPI compare #2 0 (null) == 0 (1 limb) +mbedtls_mpi_cmp_mpi:"":"0":0 + +MPI compare #3 0 (null) < positive +mbedtls_mpi_cmp_mpi:"":"7b":-1 + +MPI compare #4 0 (null) > negative +mbedtls_mpi_cmp_mpi:"":"-7b":1 + +MPI compare #5 0 (null) < positive with leading zero limb +mbedtls_mpi_cmp_mpi:"":"0000000000000000123":-1 + +MPI compare #6 0 (null) > negative with leading zero limb +mbedtls_mpi_cmp_mpi:"":"-0000000000000000123":1 + +MPI compare #7 0 (null) < large positive +mbedtls_mpi_cmp_mpi:"":"1230000000000000000":-1 + +MPI compare #8 0 (null) > large negative +mbedtls_mpi_cmp_mpi:"":"-1230000000000000000":1 + +MPI compare #9 0 (1 limb) == 0 (1 limb) +mbedtls_mpi_cmp_mpi:"0":"0":0 + +MPI compare #10 0 (1 limb) < positive +mbedtls_mpi_cmp_mpi:"0":"7b":-1 + +MPI compare #11 0 (1 limb) > negative +mbedtls_mpi_cmp_mpi:"0":"-7b":1 + +MPI compare #12 0 (1 limb) < positive with leading zero limb +mbedtls_mpi_cmp_mpi:"0":"0000000000000000123":-1 + +MPI compare #13 0 (1 limb) > negative with leading zero limb +mbedtls_mpi_cmp_mpi:"0":"-0000000000000000123":1 + +MPI compare #14 0 (1 limb) < large positive +mbedtls_mpi_cmp_mpi:"0":"1230000000000000000":-1 + +MPI compare #15 0 (1 limb) > large negative +mbedtls_mpi_cmp_mpi:"0":"-1230000000000000000":1 + +MPI compare #16 positive == positive +mbedtls_mpi_cmp_mpi:"7b":"7b":0 + +MPI compare #17 positive > negative +mbedtls_mpi_cmp_mpi:"7b":"-7b":1 + +MPI compare #18 positive < positive with leading zero limb +mbedtls_mpi_cmp_mpi:"7b":"0000000000000000123":-1 + +MPI compare #19 positive > negative with leading zero limb +mbedtls_mpi_cmp_mpi:"7b":"-0000000000000000123":1 + +MPI compare #20 positive < large positive +mbedtls_mpi_cmp_mpi:"7b":"1230000000000000000":-1 + +MPI compare #21 positive > large negative +mbedtls_mpi_cmp_mpi:"7b":"-1230000000000000000":1 + +MPI compare #22 negative == negative +mbedtls_mpi_cmp_mpi:"-7b":"-7b":0 + +MPI compare #23 negative < positive with leading zero limb +mbedtls_mpi_cmp_mpi:"-7b":"0000000000000000123":-1 + +MPI compare #24 negative > negative with leading zero limb +mbedtls_mpi_cmp_mpi:"-7b":"-0000000000000000123":1 + +MPI compare #25 negative < large positive +mbedtls_mpi_cmp_mpi:"-7b":"1230000000000000000":-1 + +MPI compare #26 negative > large negative +mbedtls_mpi_cmp_mpi:"-7b":"-1230000000000000000":1 + +MPI compare #27 positive with leading zero limb == positive with leading zero limb +mbedtls_mpi_cmp_mpi:"0000000000000000123":"0000000000000000123":0 + +MPI compare #28 positive with leading zero limb > negative with leading zero limb +mbedtls_mpi_cmp_mpi:"0000000000000000123":"-0000000000000000123":1 + +MPI compare #29 positive with leading zero limb < large positive +mbedtls_mpi_cmp_mpi:"0000000000000000123":"1230000000000000000":-1 + +MPI compare #30 positive with leading zero limb > large negative +mbedtls_mpi_cmp_mpi:"0000000000000000123":"-1230000000000000000":1 + +MPI compare #31 negative with leading zero limb == negative with leading zero limb +mbedtls_mpi_cmp_mpi:"-0000000000000000123":"-0000000000000000123":0 + +MPI compare #32 negative with leading zero limb < large positive +mbedtls_mpi_cmp_mpi:"-0000000000000000123":"1230000000000000000":-1 + +MPI compare #33 negative with leading zero limb > large negative +mbedtls_mpi_cmp_mpi:"-0000000000000000123":"-1230000000000000000":1 + +MPI compare #34 large positive == large positive +mbedtls_mpi_cmp_mpi:"1230000000000000000":"1230000000000000000":0 + +MPI compare #35 large positive > large negative +mbedtls_mpi_cmp_mpi:"1230000000000000000":"-1230000000000000000":1 + +MPI compare #36 large negative == large negative +mbedtls_mpi_cmp_mpi:"-1230000000000000000":"-1230000000000000000":0 + +MPI compare #37 negative > negative +mbedtls_mpi_cmp_mpi:"-2":"-3":1 + +MPI compare #38 negative == negative +mbedtls_mpi_cmp_mpi:"-2":"-2":0 + +MPI compare #39 positive < positive +mbedtls_mpi_cmp_mpi:"2b4":"2b5":-1 + +MPI compare #40 positive < positive +mbedtls_mpi_cmp_mpi:"2b5":"2b6":-1 + +MPI compare (abs) #1 0 (null) == 0 (null) +mbedtls_mpi_cmp_abs:"":"":0 + +MPI compare (abs) #2 0 (null) == 0 (1 limb) +mbedtls_mpi_cmp_abs:"":"0":0 + +MPI compare (abs) #3 0 (null) < positive +mbedtls_mpi_cmp_abs:"":"7b":-1 + +MPI compare (abs) #4 0 (null) < positive +mbedtls_mpi_cmp_abs:"":"7b":-1 + +MPI compare (abs) #5 0 (null) < positive with leading zero limb +mbedtls_mpi_cmp_abs:"":"0000000000000000123":-1 + +MPI compare (abs) #6 0 (null) < positive with leading zero limb +mbedtls_mpi_cmp_abs:"":"0000000000000000123":-1 + +MPI compare (abs) #7 0 (null) < large positive +mbedtls_mpi_cmp_abs:"":"1230000000000000000":-1 + +MPI compare (abs) #8 0 (null) < large positive +mbedtls_mpi_cmp_abs:"":"1230000000000000000":-1 + +MPI compare (abs) #9 0 (1 limb) == 0 (1 limb) +mbedtls_mpi_cmp_abs:"0":"0":0 + +MPI compare (abs) #10 0 (1 limb) < positive +mbedtls_mpi_cmp_abs:"0":"7b":-1 + +MPI compare (abs) #11 0 (1 limb) < positive +mbedtls_mpi_cmp_abs:"0":"7b":-1 + +MPI compare (abs) #12 0 (1 limb) < positive with leading zero limb +mbedtls_mpi_cmp_abs:"0":"0000000000000000123":-1 + +MPI compare (abs) #13 0 (1 limb) < positive with leading zero limb +mbedtls_mpi_cmp_abs:"0":"0000000000000000123":-1 + +MPI compare (abs) #14 0 (1 limb) < large positive +mbedtls_mpi_cmp_abs:"0":"1230000000000000000":-1 + +MPI compare (abs) #15 0 (1 limb) < large positive +mbedtls_mpi_cmp_abs:"0":"1230000000000000000":-1 + +MPI compare (abs) #16 positive == positive +mbedtls_mpi_cmp_abs:"7b":"7b":0 + +MPI compare (abs) #17 positive == positive +mbedtls_mpi_cmp_abs:"7b":"7b":0 + +MPI compare (abs) #18 positive < positive with leading zero limb +mbedtls_mpi_cmp_abs:"7b":"0000000000000000123":-1 + +MPI compare (abs) #19 positive < positive with leading zero limb +mbedtls_mpi_cmp_abs:"7b":"0000000000000000123":-1 + +MPI compare (abs) #20 positive < large positive +mbedtls_mpi_cmp_abs:"7b":"1230000000000000000":-1 + +MPI compare (abs) #21 positive < large positive +mbedtls_mpi_cmp_abs:"7b":"1230000000000000000":-1 + +MPI compare (abs) #22 positive == positive +mbedtls_mpi_cmp_abs:"7b":"7b":0 + +MPI compare (abs) #23 positive < positive with leading zero limb +mbedtls_mpi_cmp_abs:"7b":"0000000000000000123":-1 + +MPI compare (abs) #24 positive < positive with leading zero limb +mbedtls_mpi_cmp_abs:"7b":"0000000000000000123":-1 + +MPI compare (abs) #25 positive < large positive +mbedtls_mpi_cmp_abs:"7b":"1230000000000000000":-1 + +MPI compare (abs) #26 positive < large positive +mbedtls_mpi_cmp_abs:"7b":"1230000000000000000":-1 + +MPI compare (abs) #27 positive with leading zero limb == positive with leading zero limb +mbedtls_mpi_cmp_abs:"0000000000000000123":"0000000000000000123":0 + +MPI compare (abs) #28 positive with leading zero limb == positive with leading zero limb +mbedtls_mpi_cmp_abs:"0000000000000000123":"0000000000000000123":0 + +MPI compare (abs) #29 positive with leading zero limb < large positive +mbedtls_mpi_cmp_abs:"0000000000000000123":"1230000000000000000":-1 + +MPI compare (abs) #30 positive with leading zero limb < large positive +mbedtls_mpi_cmp_abs:"0000000000000000123":"1230000000000000000":-1 + +MPI compare (abs) #31 positive with leading zero limb == positive with leading zero limb +mbedtls_mpi_cmp_abs:"0000000000000000123":"0000000000000000123":0 + +MPI compare (abs) #32 positive with leading zero limb < large positive +mbedtls_mpi_cmp_abs:"0000000000000000123":"1230000000000000000":-1 + +MPI compare (abs) #33 positive with leading zero limb < large positive +mbedtls_mpi_cmp_abs:"0000000000000000123":"1230000000000000000":-1 + +MPI compare (abs) #34 large positive == large positive +mbedtls_mpi_cmp_abs:"1230000000000000000":"1230000000000000000":0 + +MPI compare (abs) #35 large positive == large positive +mbedtls_mpi_cmp_abs:"1230000000000000000":"1230000000000000000":0 + +MPI compare (abs) #36 large positive == large positive +mbedtls_mpi_cmp_abs:"1230000000000000000":"1230000000000000000":0 + +MPI compare (abs) #37 positive < positive +mbedtls_mpi_cmp_abs:"2":"3":-1 + +MPI compare (abs) #38 positive == positive +mbedtls_mpi_cmp_abs:"2":"2":0 + +MPI compare (abs) #39 positive < positive +mbedtls_mpi_cmp_abs:"2b4":"2b5":-1 + +MPI compare (abs) #40 positive < positive +mbedtls_mpi_cmp_abs:"2b5":"2b6":-1 + +# End of automatically generated file.