diff --git a/.gitignore b/.gitignore index 24df397ed..2843404d0 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,12 @@ __pycache__ .pytest_cache # Ignore key materials generated by examples or tests test_keyrings/ +# Ignore results of performance test +performance_tests/results/*.csv +performance_tests/results/*.pstats +performance_tests/results/*.png +# Ignore the memory profile logs +mprofile_* # PyCharm .idea/ diff --git a/buildspec.yml b/buildspec.yml index 873e5941e..792579467 100644 --- a/buildspec.yml +++ b/buildspec.yml @@ -164,6 +164,10 @@ batch: buildspec: codebuild/py311/integ_mpl.yml env: image: aws/codebuild/standard:7.0 + - identifier: py311_performance_tests_mpl + buildspec: codebuild/py311/performance_tests_mpl.yml + env: + image: aws/codebuild/standard:7.0 - identifier: py311_examples buildspec: codebuild/py311/examples.yml env: @@ -250,6 +254,10 @@ batch: buildspec: codebuild/py312/integ_mpl.yml env: image: aws/codebuild/standard:7.0 + - identifier: py312_performance_tests_mpl + buildspec: codebuild/py312/performance_tests_mpl.yml + env: + image: aws/codebuild/standard:7.0 - identifier: py312_examples buildspec: codebuild/py312/examples.yml env: diff --git a/codebuild/py311/performance_tests_mpl.yml b/codebuild/py311/performance_tests_mpl.yml new file mode 100644 index 000000000..2debb1185 --- /dev/null +++ b/codebuild/py311/performance_tests_mpl.yml @@ -0,0 +1,38 @@ +# Runs the performance tests for the MPL in an environment with the MPL installed +version: 0.2 + +env: + variables: + # No TOXENV. This runs multiple environments. + REGION: "us-west-2" + AWS_ENCRYPTION_SDK_PYTHON_INTEGRATION_TEST_AWS_KMS_KEY_ID: >- + arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f + AWS_ENCRYPTION_SDK_PYTHON_INTEGRATION_TEST_AWS_KMS_KEY_ID_2: >- + arn:aws:kms:eu-central-1:658956600833:key/75414c93-5285-4b57-99c9-30c1cf0a22c2 + AWS_ENCRYPTION_SDK_PYTHON_INTEGRATION_TEST_AWS_KMS_MRK_KEY_ID_1: >- + arn:aws:kms:us-west-2:658956600833:key/mrk-80bd8ecdcd4342aebd84b7dc9da498a7 + AWS_ENCRYPTION_SDK_PYTHON_INTEGRATION_TEST_AWS_KMS_MRK_KEY_ID_2: >- + arn:aws:kms:us-east-1:658956600833:key/mrk-80bd8ecdcd4342aebd84b7dc9da498a7 + +phases: + install: + runtime-versions: + python: 3.11 + build: + commands: + - cd /root/.pyenv/plugins/python-build/../.. && git pull && cd - + - pyenv install --skip-existing 3.11.0 + - pyenv local 3.11.0 + - pip install --upgrade pip + - pip install setuptools + - pip install "tox < 4.0" + # Assume special role to access keystore + - TMP_ROLE=$(aws sts assume-role --role-arn "arn:aws:iam::370957321024:role/GitHub-CI-Public-ESDK-Python-Role-us-west-2" --role-session-name "CB-Py312ExamplesMpl") + - export TMP_ROLE + - export AWS_ACCESS_KEY_ID=$(echo "${TMP_ROLE}" | jq -r '.Credentials.AccessKeyId') + - export AWS_SECRET_ACCESS_KEY=$(echo "${TMP_ROLE}" | jq -r '.Credentials.SecretAccessKey') + - export AWS_SESSION_TOKEN=$(echo "${TMP_ROLE}" | jq -r '.Credentials.SessionToken') + - aws sts get-caller-identity + # Run MPL-specific tests with special role + - cd performance_tests/ + - tox -e py311-performance_tests-mpl diff --git a/codebuild/py312/performance_tests_mpl.yml b/codebuild/py312/performance_tests_mpl.yml new file mode 100644 index 000000000..97dbf359f --- /dev/null +++ b/codebuild/py312/performance_tests_mpl.yml @@ -0,0 +1,38 @@ +# Runs the performance tests for the MPL in an environment with the MPL installed +version: 0.2 + +env: + variables: + # No TOXENV. This runs multiple environments. + REGION: "us-west-2" + AWS_ENCRYPTION_SDK_PYTHON_INTEGRATION_TEST_AWS_KMS_KEY_ID: >- + arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f + AWS_ENCRYPTION_SDK_PYTHON_INTEGRATION_TEST_AWS_KMS_KEY_ID_2: >- + arn:aws:kms:eu-central-1:658956600833:key/75414c93-5285-4b57-99c9-30c1cf0a22c2 + AWS_ENCRYPTION_SDK_PYTHON_INTEGRATION_TEST_AWS_KMS_MRK_KEY_ID_1: >- + arn:aws:kms:us-west-2:658956600833:key/mrk-80bd8ecdcd4342aebd84b7dc9da498a7 + AWS_ENCRYPTION_SDK_PYTHON_INTEGRATION_TEST_AWS_KMS_MRK_KEY_ID_2: >- + arn:aws:kms:us-east-1:658956600833:key/mrk-80bd8ecdcd4342aebd84b7dc9da498a7 + +phases: + install: + runtime-versions: + python: 3.12 + build: + commands: + - cd /root/.pyenv/plugins/python-build/../.. && git pull && cd - + - pyenv install --skip-existing 3.12.0 + - pyenv local 3.12.0 + - pip install --upgrade pip + - pip install setuptools + - pip install "tox < 4.0" + # Assume special role to access keystore + - TMP_ROLE=$(aws sts assume-role --role-arn "arn:aws:iam::370957321024:role/GitHub-CI-Public-ESDK-Python-Role-us-west-2" --role-session-name "CB-Py312ExamplesMpl") + - export TMP_ROLE + - export AWS_ACCESS_KEY_ID=$(echo "${TMP_ROLE}" | jq -r '.Credentials.AccessKeyId') + - export AWS_SECRET_ACCESS_KEY=$(echo "${TMP_ROLE}" | jq -r '.Credentials.SecretAccessKey') + - export AWS_SESSION_TOKEN=$(echo "${TMP_ROLE}" | jq -r '.Credentials.SessionToken') + - aws sts get-caller-identity + # Run MPL-specific tests with special role + - cd performance_tests/ + - tox -e py312-performance_tests-mpl diff --git a/performance_tests/README.rst b/performance_tests/README.rst new file mode 100644 index 000000000..ba9b89f15 --- /dev/null +++ b/performance_tests/README.rst @@ -0,0 +1,219 @@ +##################################### +aws-encryption-sdk performance tests +##################################### + +This module runs performance tests for the `AWS Encryption SDK Python`_. + +******** +Overview +******** + +This module tests the following keyrings / master key providers: + +1. KMS Keyring / KMS Master Key Provider +2. Raw AES Keyring / AES Master Key Provider +3. Raw RSA Keyring / RSA Master Key Provider +4. Hierarchy Keyring +5. Caching CMM + +For each test on the above keyrings / master key providers, this package measures: + +1. Execution time +2. Total memory consumption + +For each keyring / master key provider, the execution time and memory consumption +is measured for three operations: + +1. Create keyring / master key provider +2. Encrypt +3. Decrypt + +The usage of the performance tests is demonstrated through an `AWS KMS Keyring`_. +However, the procedure is the same for any keyring / master key provider, with slight +changes in the input arguments. + +The results for the performance test will be available in the results folder in the +performance_tests directory. + +********************** +Required Prerequisites +********************** + +* Python 3.8+ +* aws-encryption-sdk +* boto3 >= 1.10.0 +* click +* tqdm +* pytest + +Recommended Prerequisites +========================= + +* aws-cryptographic-material-providers: >= 1.0.0 + * Requires Python 3.11+. + +***** +Usage +***** + +Execution Time +============== + +Create Keyring +-------------- +To run the performance test for execution time, please use the +following commands in the performance_tests directory. + +.. code:: + + usage: python test/keyrings/test_aws_kms_keyring.py create + + Create a keyring to use for encryption and decryption. + + optional arguments: + -h, --help show this help message and exit. + --kms_key_id KMS_KEY_ID The KMS key ID you want to use. + --n_iters N_ITERS Number of iterations you want to + run the test for. For instance, + if n_iters = 100, this performance + test script will run the create_keyring + method 100 times and report the + execution time of each of the calls. + --output_file OUTPUT_FILE The output file for execution times + for each function call, + default='kms_keyring_create' in the + results folder. + +Encrypt +------- + +To run the performance test for execution time, please use the following +commands in the performance_tests directory: + +.. code:: + + usage: python test/keyrings/test_aws_kms_keyring.py encrypt + + optional arguments: + -h, --help show this help message and exit. + --plaintext_data_filename PLAINTEXT_DATA_FILENAME Filename containing plaintext data + you want to encrypt. + default='test/resources/plaintext/plaintext-data-medium.dat'. + You can choose to use any other plaintext + file as well. Some example plaintext + data files are present in the + 'test/resources' directory. + --kms_key_id KMS_KEY_ID The KMS key ID you want to use. + --n_iters N_ITERS Number of iterations you want to + run the test for. For instance, + if n_iters = 100, this performance + test script will run the create_keyring + method 100 times and report the + execution time of each of the calls. + --output_file OUTPUT_FILE The output file for execution times + for each function call, + default='kms_keyring_create' in the + results folder. + +Decrypt +------- + +To run the performance test for execution time, please use the +following commands in the performance_tests directory + +.. code:: + + usage: python test/keyrings/test_aws_kms_keyring.py decrypt + + optional arguments: + -h, --help show this help message and exit. + --ciphertext_data_filename CIPHERTEXT_DATA_FILENAME Filename containing ciphertext data + you want to decrypt. + default='test/resources/ciphertext/kms/ciphertext-data-medium.ct'. + You can choose to use any other + ciphertext file as well. Some example + ciphertext data files are present in + the 'test/resources' directory. + --kms_key_id KMS_KEY_ID The KMS key ID you want to use. + --n_iters N_ITERS Number of iterations you want to + run the test for. For instance, + if n_iters = 100, this performance + test script will run the create_keyring + method 100 times and report the + execution time of each of the calls. + --output_file OUTPUT_FILE The output file for execution times + for each function call, + default='kms_keyring_create' in the + results folder. + +Consolidate Time Results +======================== + +In order to find the minimum, maximum, average, 99th percentile and bottom +99th percentile trimmed average times from the n_iters runs, please use the +following script from the performance_tests directory with the csv file +containing times for each of the n_iters runs generated in the previous +"Execution Time" section: + +.. code:: + + usage: python consolidate_results.py results/kms_keyring_decrypt.csv + +Memory Consumption +================== + +To get the memory consumption, simply replace 'python' +with 'mprof run' in the previously mentioned commands. + +For example, if you want to calculate the memory consumption +of the encrypt function of a AWS KMS Keyring, simply write: + +.. code:: + + usage: mprof run test/keyrings/test_aws_kms_keyring.py encrypt + + +This should generate an mprofile log file in your current directory. +This mprofile log file contains the total memory consumed by the program +with respect to time elapsed. +To plot the memory consumption with respect to time, please use the following +command from the same directory + +.. code:: + + usage: mprof plot + + +This 'mprof plot' command will plot the most recent mprofile log file. + + +Performance Graph +================= + +To generate a performance graph, please use the following command +to generate the pstats log file by specifying the output pstats file +path. Here, 'results/kms_keyring_create.pstats' is set as the default +output file. + +.. code:: + + usage: python -m cProfile -o results/kms_keyring_create.pstats test/keyrings/test_aws_kms_keyring.py create + + +After generating the pstats file, please run the following command +to generate the performance graph. The output performance graph will +be a .png file that you specify. Here, 'results/kms_keyring_create.png' +is set as the default output file. + +.. code:: + + usage: gprof2dot -f pstats results/kms_keyring_create.pstats | dot -Tpng -o results/kms_keyring_create.png && eog results/kms_keyring_create.png + + +Note: This project does not adhere to semantic versioning; as such it +makes no guarantees that functionality will persist across major, +minor, or patch versions. +**DO NOT** take a standalone dependency on this library. + +.. _AWS Encryption SDK Python: https://github.com/aws/aws-encryption-sdk-python/ +.. _AWS KMS Keyring: https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/use-kms-keyring.html diff --git a/performance_tests/__init__.py b/performance_tests/__init__.py new file mode 100644 index 000000000..120179eda --- /dev/null +++ b/performance_tests/__init__.py @@ -0,0 +1,3 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +"""Stub module indicator to make linter configuration simpler.""" diff --git a/performance_tests/consolidate_results.py b/performance_tests/consolidate_results.py new file mode 100644 index 000000000..2601417cc --- /dev/null +++ b/performance_tests/consolidate_results.py @@ -0,0 +1,49 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +"""Script for consolidating results for execution times""" + +import argparse +import csv + +import numpy as np + + +def calculate_statistics(_csv_file): + """Calculate average, trimmed average, minimum, maximum and p99 statistics for execution times in a CSV file.""" + with open(_csv_file, 'r', encoding='utf-8') as file: + reader = csv.reader(file) + data = [float(row[0]) for row in reader] + + output_stats = {} + + # Calculate statistics + if data: + data = np.sort(data) + output_stats['total_entries'] = len(data) + output_stats['average'] = np.mean(data) + output_stats['trimmed_average_99_bottom'] = np.mean(data[0:int(0.99 * len(data))]) + output_stats['minimum'] = min(data) + output_stats['maximum'] = max(data) + output_stats['perc_99'] = np.percentile(data, 99) + return output_stats + + return None + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument('csv_file', + help='csv file containing the outputs of execution times for n_iter iterations') + args = parser.parse_args() + + statistics = calculate_statistics(args.csv_file) + if statistics: + print("CSV File:", args.csv_file) + print("Total Entries:", statistics['total_entries']) + print("Average:", statistics['average']) + print("Bottom 99th percentile trimmed average:", statistics['trimmed_average_99_bottom']) + print("Minimum:", statistics['minimum']) + print("Maximum:", statistics['maximum']) + print("99th percentile:", statistics['perc_99']) + else: + print("No data found in the CSV file.") diff --git a/performance_tests/pylintrc b/performance_tests/pylintrc new file mode 100644 index 000000000..8ed5cb105 --- /dev/null +++ b/performance_tests/pylintrc @@ -0,0 +1,45 @@ +[MESSAGE CONTROL] +# Disabling messages that either we don't care about we intentionally break. +disable = + import-error, # ignore mpl import errors + invalid-name, # we prefer long, descriptive, names for examples + bad-continuation, # we let black handle this + ungrouped-imports, # we let isort handle this + no-member, # breaks with attrs + no-self-use, # interesting to keep in mind for later refactoring, but not blocking + useless-object-inheritance, # we need to support Python 2, so no, not useless + duplicate-code, # some examples may be similar + too-few-public-methods, # does not allow value stores + too-many-locals, # examples may sometimes have more locals defined for clarity than would be appropriate in code + no-else-return, # we omit this on purpose for brevity where it would add no value + attribute-defined-outside-init, # breaks with attrs_post_init + abstract-method, # throws false positives on io.BaseIO grandchildren + redefined-outer-name, # we do this on purpose in multiple places + consider-using-f-string # disable until 2022-05-05; 6 months after 3.5 deprecation + +[BASIC] +# Allow function names up to 50 characters +function-rgx = [a-z_][a-z0-9_]{2,50}$ +# Allow method names up to 50 characters +method-rgx = [a-z_][a-z0-9_]{2,50}$ +# Allow class attribute names up to 50 characters +# Whitelist class attribute names: iv +class-attribute-rgx = (([A-Za-z_][A-Za-z0-9_]{2,50}|(__.*__))$)|(^iv$) +# Whitelist attribute names: iv +attr-rgx = ([a-z_][a-z0-9_]{2,30}$)|(^iv$) +# Whitelist argument names: iv, b +argument-rgx = ([a-z_][a-z0-9_]{2,30}$)|(^iv$)|(^b$) +# Whitelist variable names: iv, b, _b, x, y, r, s +variable-rgx = ([a-z_][a-z0-9_]{2,30}$)|(^iv$)|(^b$)|(^_b$)|(^x$)|(^y$)|(^r$)|(^s$) + +[VARIABLES] +additional-builtins = raw_input + +[DESIGN] +max-args = 10 + +[FORMAT] +max-line-length = 120 + +[REPORTS] +msg-template = {path}:{line}: [{msg_id}({symbol}), {obj}] {msg} diff --git a/performance_tests/requirements.txt b/performance_tests/requirements.txt new file mode 100644 index 000000000..0b879647f --- /dev/null +++ b/performance_tests/requirements.txt @@ -0,0 +1,5 @@ +attrs >= 17.4.0 +aws-encryption-sdk>=2.3.0 +pytest>=3.3.1 +tqdm +click diff --git a/performance_tests/requirements_mpl.txt b/performance_tests/requirements_mpl.txt new file mode 100644 index 000000000..209e10f2c --- /dev/null +++ b/performance_tests/requirements_mpl.txt @@ -0,0 +1 @@ +aws-cryptographic-material-providers @ git+https://github.com/aws/aws-cryptographic-material-providers-library.git@lucmcdon/python-mpl#subdirectory=AwsCryptographicMaterialProviders/runtimes/python \ No newline at end of file diff --git a/performance_tests/results/.gitkeep b/performance_tests/results/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/performance_tests/setup.cfg b/performance_tests/setup.cfg new file mode 100644 index 000000000..c584a25bd --- /dev/null +++ b/performance_tests/setup.cfg @@ -0,0 +1,41 @@ +[wheel] +universal = 1 + +[metadata] +license_file = LICENSE + +[coverage:run] +branch = True + +[coverage:report] +show_missing = True + +[mypy] +ignore_missing_imports = True + +[flake8] +max_complexity = 10 +max_line_length = 120 +import_order_style = google +application_import_names = aws_encryption_sdk_cli +builtins = raw_input +ignore = + # Ignoring D205 and D400 because of false positives + D205, D400, + # E203 is not PEP8 compliant https://github.com/ambv/black#slices + E203, + # W503 is not PEP8 compliant https://github.com/ambv/black#line-breaks--binary-operators + W503 + +[doc8] +max-line-length = 120 + +[isort] +line_length = 120 +# https://github.com/timothycrosley/isort#multi-line-output-modes +multi_line_output = 3 +include_trailing_comma = True +force_grid_wrap = 0 +combine_as_imports = True +not_skip = __init__.py +known_third_party = attr,aws_encryption_sdk,pytest,setuptools,six diff --git a/performance_tests/setup.py b/performance_tests/setup.py new file mode 100644 index 000000000..702813509 --- /dev/null +++ b/performance_tests/setup.py @@ -0,0 +1,34 @@ +"""Performance test for the AWS Encryption SDK for Python.""" +import os +import re + +from setuptools import find_packages, setup + +VERSION_RE = re.compile(r"""__version__ = ['"]([0-9.]+)['"]""") +HERE = os.path.abspath(os.path.dirname(__file__)) + + +def read(*args): + """Read complete file contents.""" + return open(os.path.join(HERE, *args), encoding="utf-8").read() # pylint: disable=consider-using-with + + +def get_version(): + """Read the version from this module.""" + init = read("src", "aws_encryption_sdk_performance_tests", "__init__.py") + return VERSION_RE.search(init).group(1) + + +setup( + name="aws-encryption-sdk-performance-tests", + packages=find_packages("src"), + package_dir={"": "src"}, + author="Amazon Web Services", + maintainer="Amazon Web Services", + author_email="aws-cryptools@amazon.com", + url="https://github.com/awslabs/aws-encryption-sdk-python", + description="Performance tests for the AWS Encryption SDK for Python", + keywords="aws-encryption-sdk aws kms encryption", + license="Apache License 2.0", + version=get_version(), +) diff --git a/performance_tests/src/aws_encryption_sdk_performance_tests/__init__.py b/performance_tests/src/aws_encryption_sdk_performance_tests/__init__.py new file mode 100644 index 000000000..cf1bf0fb4 --- /dev/null +++ b/performance_tests/src/aws_encryption_sdk_performance_tests/__init__.py @@ -0,0 +1,4 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +"""Stub module indicator to make linter configuration simpler.""" +__version__ = "0.1.0" diff --git a/performance_tests/src/aws_encryption_sdk_performance_tests/keyrings/__init__.py b/performance_tests/src/aws_encryption_sdk_performance_tests/keyrings/__init__.py new file mode 100644 index 000000000..120179eda --- /dev/null +++ b/performance_tests/src/aws_encryption_sdk_performance_tests/keyrings/__init__.py @@ -0,0 +1,3 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +"""Stub module indicator to make linter configuration simpler.""" diff --git a/performance_tests/src/aws_encryption_sdk_performance_tests/keyrings/aws_kms_keyring.py b/performance_tests/src/aws_encryption_sdk_performance_tests/keyrings/aws_kms_keyring.py new file mode 100644 index 000000000..e846ec695 --- /dev/null +++ b/performance_tests/src/aws_encryption_sdk_performance_tests/keyrings/aws_kms_keyring.py @@ -0,0 +1,131 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +"""Performance tests for the AWS KMS keyring.""" + +import aws_encryption_sdk +import boto3 +from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders +from aws_cryptographic_materialproviders.mpl.config import MaterialProvidersConfig +from aws_cryptographic_materialproviders.mpl.models import CreateAwsKmsKeyringInput +from aws_cryptographic_materialproviders.mpl.references import IKeyring + + +def create_keyring( + kms_key_id: str +): + """Demonstrate how to create an AWS KMS keyring. + + Usage: create_keyring(kms_key_id) + :param kms_key_id: KMS Key identifier for the KMS key you want to use. + :type kms_key_id: string + + For more information on KMS Key identifiers, see + https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id + """ + # Create a boto3 client for KMS. + kms_client = create_kms_client() + + # Create a KMS keyring + mat_prov: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders( + config=MaterialProvidersConfig() + ) + + keyring_input: CreateAwsKmsKeyringInput = CreateAwsKmsKeyringInput( + kms_key_id=kms_key_id, + kms_client=kms_client + ) + + keyring: IKeyring = mat_prov.create_aws_kms_keyring( + input=keyring_input + ) + + return keyring + + +def create_kms_client(aws_region="us-west-2"): + """Create an AWS KMS client. + + Usage: create_kms_client(aws_region) + :param aws_region: AWS region to use for KMS client. + :type aws_region: string + """ + # Create a boto3 client for KMS. + kms_client = boto3.client('kms', region_name=aws_region) + + return kms_client + + +def create_keyring_given_kms_client( + kms_key_id: str, + kms_client: boto3.client, +): + """Demonstrate how to create an AWS KMS keyring with given KMS client. + + Usage: create_keyring(kms_key_id, kms_client) + :param kms_key_id: KMS Key identifier for the KMS key you want to use. + :type kms_key_id: string + :param kms_client: boto3 client for KMS. + :type kms_client: boto3.client + + For more information on KMS Key identifiers, see + https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id + """ + # Create a KMS keyring + mat_prov: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders( + config=MaterialProvidersConfig() + ) + + keyring_input: CreateAwsKmsKeyringInput = CreateAwsKmsKeyringInput( + kms_key_id=kms_key_id, + kms_client=kms_client + ) + + keyring: IKeyring = mat_prov.create_aws_kms_keyring( + input=keyring_input + ) + + return keyring + + +def encrypt_using_keyring( + plaintext_data: bytes, + keyring: IKeyring +): + """Demonstrate how to encrypt plaintext data using an AWS KMS keyring. + + Usage: encrypt_using_keyring(plaintext_data, keyring) + :param plaintext_data: plaintext data you want to encrypt + :type: bytes + :param keyring: Keyring to use for encryption. + :type keyring: IKeyring + """ + client = aws_encryption_sdk.EncryptionSDKClient() + + ciphertext_data, _ = client.encrypt( + source=plaintext_data, + keyring=keyring + ) + + return ciphertext_data + + +def decrypt_using_keyring( + ciphertext_data: bytes, + keyring: IKeyring +): + """Demonstrate how to decrypt ciphertext data using an AWS KMS keyring. + + Usage: decrypt_using_keyring(ciphertext_data, keyring) + :param ciphertext_data: ciphertext data you want to decrypt + :type: bytes + :param keyring: Keyring to use for decryption. + :type keyring: IKeyring + """ + client = aws_encryption_sdk.EncryptionSDKClient() + + decrypted_plaintext_data, _ = client.decrypt( + source=ciphertext_data, + keyring=keyring + ) + + return decrypted_plaintext_data diff --git a/performance_tests/src/aws_encryption_sdk_performance_tests/keyrings/raw_aes_keyring.py b/performance_tests/src/aws_encryption_sdk_performance_tests/keyrings/raw_aes_keyring.py new file mode 100644 index 000000000..a849b1a7f --- /dev/null +++ b/performance_tests/src/aws_encryption_sdk_performance_tests/keyrings/raw_aes_keyring.py @@ -0,0 +1,85 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +"""Performance tests for the Raw AES keyring.""" + +import aws_encryption_sdk +from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders +from aws_cryptographic_materialproviders.mpl.config import MaterialProvidersConfig +from aws_cryptographic_materialproviders.mpl.models import AesWrappingAlg, CreateRawAesKeyringInput +from aws_cryptographic_materialproviders.mpl.references import IKeyring + +from ..utils.util import PerfTestUtils + + +def create_keyring(): + """Demonstrate how to create a Raw AES keyring. + + Usage: create_keyring() + """ + key_name_space = "Some managed raw keys" + key_name = "My 256-bit AES wrapping key" + + # Here, the input to secrets.token_bytes() = 32 bytes = 256 bits + # We fix the static key in order to make the test deterministic + static_key = PerfTestUtils.DEFAULT_AES_256_STATIC_KEY + + mat_prov: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders( + config=MaterialProvidersConfig() + ) + + keyring_input: CreateRawAesKeyringInput = CreateRawAesKeyringInput( + key_namespace=key_name_space, + key_name=key_name, + wrapping_key=static_key, + wrapping_alg=AesWrappingAlg.ALG_AES256_GCM_IV12_TAG16 + ) + + keyring: IKeyring = mat_prov.create_raw_aes_keyring( + input=keyring_input + ) + + return keyring + + +def encrypt_using_keyring( + plaintext_data: bytes, + keyring: IKeyring +): + """Demonstrate how to encrypt plaintext data using a Raw AES keyring. + + Usage: encrypt_using_keyring(plaintext_data, keyring) + :param plaintext_data: plaintext data you want to encrypt + :type: bytes + :param keyring: Keyring to use for encryption. + :type keyring: IKeyring + """ + client = aws_encryption_sdk.EncryptionSDKClient() + + ciphertext_data, _ = client.encrypt( + source=plaintext_data, + keyring=keyring + ) + + return ciphertext_data + + +def decrypt_using_keyring( + ciphertext_data: bytes, + keyring: IKeyring +): + """Demonstrate how to decrypt ciphertext data using a Raw AES keyring. + + Usage: decrypt_using_keyring(ciphertext_data, keyring) + :param ciphertext_data: ciphertext data you want to decrypt + :type: bytes + :param keyring: Keyring to use for decryption. + :type keyring: IKeyring + """ + client = aws_encryption_sdk.EncryptionSDKClient() + + decrypted_plaintext_data, _ = client.decrypt( + source=ciphertext_data, + keyring=keyring + ) + + return decrypted_plaintext_data diff --git a/performance_tests/src/aws_encryption_sdk_performance_tests/keyrings/raw_rsa_keyring.py b/performance_tests/src/aws_encryption_sdk_performance_tests/keyrings/raw_rsa_keyring.py new file mode 100644 index 000000000..6eed281bd --- /dev/null +++ b/performance_tests/src/aws_encryption_sdk_performance_tests/keyrings/raw_rsa_keyring.py @@ -0,0 +1,79 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +"""Performance tests for the Raw RSA keyring.""" +import aws_encryption_sdk +from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders +from aws_cryptographic_materialproviders.mpl.config import MaterialProvidersConfig +from aws_cryptographic_materialproviders.mpl.models import CreateRawRsaKeyringInput, PaddingScheme +from aws_cryptographic_materialproviders.mpl.references import IKeyring + + +def create_keyring(public_key, private_key): + """Demonstrate how to create a Raw RSA keyring using the key pair. + + Usage: create_keyring(public_key, private_key) + """ + key_name_space = "Some managed raw keys" + key_name = "My 4096-bit RSA wrapping key" + + mat_prov: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders( + config=MaterialProvidersConfig() + ) + + keyring_input: CreateRawRsaKeyringInput = CreateRawRsaKeyringInput( + key_namespace=key_name_space, + key_name=key_name, + padding_scheme=PaddingScheme.OAEP_SHA256_MGF1, + public_key=public_key, + private_key=private_key + ) + + keyring: IKeyring = mat_prov.create_raw_rsa_keyring( + input=keyring_input + ) + + return keyring + + +def encrypt_using_keyring( + plaintext_data: bytes, + keyring: IKeyring +): + """Demonstrate how to encrypt plaintext data using a Raw RSA keyring. + + Usage: encrypt_using_keyring(plaintext_data, keyring) + :param plaintext_data: plaintext data you want to encrypt + :type: bytes + :param keyring: Keyring to use for encryption. + :type keyring: IKeyring + """ + client = aws_encryption_sdk.EncryptionSDKClient() + + ciphertext_data, _ = client.encrypt( + source=plaintext_data, + keyring=keyring + ) + + return ciphertext_data + + +def decrypt_using_keyring( + ciphertext_data: bytes, + keyring: IKeyring +): + """Demonstrate how to decrypt ciphertext data using a Raw RSA keyring. + + Usage: decrypt_using_keyring(ciphertext_data, keyring) + :param ciphertext_data: ciphertext data you want to decrypt + :type: bytes + :param keyring: Keyring to use for decryption. + :type keyring: IKeyring + """ + client = aws_encryption_sdk.EncryptionSDKClient() + + decrypted_plaintext_data, _ = client.decrypt( + source=ciphertext_data, + keyring=keyring + ) + + return decrypted_plaintext_data diff --git a/performance_tests/src/aws_encryption_sdk_performance_tests/master_key_providers/__init__.py b/performance_tests/src/aws_encryption_sdk_performance_tests/master_key_providers/__init__.py new file mode 100644 index 000000000..120179eda --- /dev/null +++ b/performance_tests/src/aws_encryption_sdk_performance_tests/master_key_providers/__init__.py @@ -0,0 +1,3 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +"""Stub module indicator to make linter configuration simpler.""" diff --git a/performance_tests/src/aws_encryption_sdk_performance_tests/master_key_providers/aws_kms_master_key_provider.py b/performance_tests/src/aws_encryption_sdk_performance_tests/master_key_providers/aws_kms_master_key_provider.py new file mode 100644 index 000000000..c3136a5c7 --- /dev/null +++ b/performance_tests/src/aws_encryption_sdk_performance_tests/master_key_providers/aws_kms_master_key_provider.py @@ -0,0 +1,69 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +"""Performance tests for the AWS KMS master key provider.""" + +import aws_encryption_sdk + + +def create_key_provider( + kms_key_id: str +): + """Demonstrate how to create an AWS KMS master key-provider. + + Usage: create_key_provider(kms_key_id) + :param kms_key_id: KMS Key identifier for the KMS key you want to use. + :type kms_key_id: string + + For more information on KMS Key identifiers, see + https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id + """ + # Create a KMS master key-provider. + key_provider = aws_encryption_sdk.StrictAwsKmsMasterKeyProvider(key_ids=[ + kms_key_id, + ]) + + return key_provider + + +def encrypt_using_key_provider( + plaintext_data: bytes, + key_provider: aws_encryption_sdk.key_providers.base.MasterKeyProvider +): + """Demonstrate how to encrypt plaintext data using an AWS KMS master key-provider. + + Usage: encrypt_using_key_provider(plaintext_data, key_provider) + :param plaintext_data: plaintext data you want to encrypt + :type: bytes + :param key_provider: Master key provider to use for encryption. + :type key_provider: aws_encryption_sdk.key_providers.base.MasterKeyProvider + """ + client = aws_encryption_sdk.EncryptionSDKClient() + + ciphertext_data, _ = client.encrypt( + source=plaintext_data, + key_provider=key_provider + ) + + return ciphertext_data + + +def decrypt_using_key_provider( + ciphertext_data: bytes, + key_provider: aws_encryption_sdk.key_providers.base.MasterKeyProvider +): + """Demonstrate how to decrypt ciphertext data using an AWS KMS master key-provider. + + Usage: decrypt_using_key_provider(ciphertext_data, key_provider) + :param ciphertext_data: ciphertext data you want to decrypt + :type: bytes + :param key_provider: Master key provider to use for decryption. + :type key_provider: aws_encryption_sdk.key_providers.base.MasterKeyProvider + """ + client = aws_encryption_sdk.EncryptionSDKClient() + + decrypted_plaintext_data, _ = client.decrypt( + source=ciphertext_data, + key_provider=key_provider + ) + + return decrypted_plaintext_data diff --git a/performance_tests/src/aws_encryption_sdk_performance_tests/master_key_providers/raw_aes_master_key_provider.py b/performance_tests/src/aws_encryption_sdk_performance_tests/master_key_providers/raw_aes_master_key_provider.py new file mode 100644 index 000000000..42d071dcf --- /dev/null +++ b/performance_tests/src/aws_encryption_sdk_performance_tests/master_key_providers/raw_aes_master_key_provider.py @@ -0,0 +1,101 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +"""Performance tests for the Raw AES master key provider.""" + +import aws_encryption_sdk +from aws_encryption_sdk.identifiers import EncryptionKeyType, WrappingAlgorithm +from aws_encryption_sdk.internal.crypto.wrapping_keys import WrappingKey +from aws_encryption_sdk.key_providers.raw import RawMasterKeyProvider + +from ..utils.util import PerfTestUtils + + +class StaticRandomMasterKeyProvider(RawMasterKeyProvider): + """Generates 256-bit keys for each unique key ID.""" + + # The Provider ID (or Provider) field in the JceMasterKey and RawMasterKey is + # equivalent to key namespace in the Raw keyrings + provider_id = "Some managed raw keys" + + def __init__(self, **kwargs): # pylint: disable=unused-argument + """Initialize empty map of keys.""" + self._static_keys = {} + + def _get_raw_key(self, key_id): + """Returns a static, randomly-generated symmetric key for the specified key ID. + + :param str key_id: Key ID + :returns: Wrapping key that contains the specified static key + :rtype: :class:`aws_encryption_sdk.internal.crypto.WrappingKey` + """ + try: + static_key = self._static_keys[key_id] + except KeyError: + # We fix the static key in order to make the test deterministic + # In practice, you should get this key from a secure key management system such as an HSM. + static_key = PerfTestUtils.DEFAULT_AES_256_STATIC_KEY + self._static_keys[key_id] = static_key + return WrappingKey( + wrapping_algorithm=WrappingAlgorithm.AES_256_GCM_IV12_TAG16_NO_PADDING, + wrapping_key=static_key, + wrapping_key_type=EncryptionKeyType.SYMMETRIC, + ) + + +def create_key_provider(): + """Demonstrate how to create a Raw AES master key-provider. + + Usage: create_key_provider() + """ + # Create a Raw AES master key-provider. + + # The Key ID field in the JceMasterKey and RawMasterKey is equivalent to key name in the Raw keyrings + key_id = "My 256-bit AES wrapping key" + key_provider = StaticRandomMasterKeyProvider() + key_provider.add_master_key(key_id) + + return key_provider + + +def encrypt_using_key_provider( + plaintext_data: bytes, + key_provider: aws_encryption_sdk.key_providers.base.MasterKeyProvider +): + """Demonstrate how to encrypt plaintext data using a Raw AES master key-provider. + + Usage: encrypt_using_key_provider(plaintext_data, key_provider) + :param plaintext_data: plaintext data you want to encrypt + :type: bytes + :param key_provider: Master key provider to use for encryption. + :type key_provider: aws_encryption_sdk.key_providers.base.MasterKeyProvider + """ + client = aws_encryption_sdk.EncryptionSDKClient() + + ciphertext_data, _ = client.encrypt( + source=plaintext_data, + key_provider=key_provider + ) + + return ciphertext_data + + +def decrypt_using_key_provider( + ciphertext_data: bytes, + key_provider: aws_encryption_sdk.key_providers.base.MasterKeyProvider +): + """Demonstrate how to decrypt ciphertext data using a Raw AES master key-provider. + + Usage: decrypt_using_key_provider(ciphertext_data, key_provider) + :param ciphertext_data: ciphertext data you want to decrypt + :type: bytes + :param key_provider: Master key provider to use for decryption. + :type key_provider: aws_encryption_sdk.key_providers.base.MasterKeyProvider + """ + client = aws_encryption_sdk.EncryptionSDKClient() + + decrypted_plaintext_data, _ = client.decrypt( + source=ciphertext_data, + key_provider=key_provider + ) + + return decrypted_plaintext_data diff --git a/performance_tests/src/aws_encryption_sdk_performance_tests/master_key_providers/raw_rsa_master_key_provider.py b/performance_tests/src/aws_encryption_sdk_performance_tests/master_key_providers/raw_rsa_master_key_provider.py new file mode 100644 index 000000000..b52b78735 --- /dev/null +++ b/performance_tests/src/aws_encryption_sdk_performance_tests/master_key_providers/raw_rsa_master_key_provider.py @@ -0,0 +1,101 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +"""Performance tests for the Raw RSA master key provider.""" + +import aws_encryption_sdk +from aws_encryption_sdk.identifiers import EncryptionKeyType, WrappingAlgorithm +from aws_encryption_sdk.internal.crypto.wrapping_keys import WrappingKey +from aws_encryption_sdk.key_providers.raw import RawMasterKeyProvider + +from aws_encryption_sdk_performance_tests.utils.util import PerfTestUtils + + +class StaticRandomMasterKeyProvider(RawMasterKeyProvider): + """Randomly generates and provides 4096-bit RSA keys consistently per unique key id.""" + + # The Provider ID (or Provider) field in the JceMasterKey and RawMasterKey is + # equivalent to key namespace in the Raw keyrings + provider_id = "Some managed raw keys" + + def __init__(self, **kwargs): # pylint: disable=unused-argument + """Initialize empty map of keys.""" + self._static_keys = {} + + def _get_raw_key(self, key_id): + """Retrieves a static, randomly generated, RSA key for the specified key id. + + :param str key_id: User-defined ID for the static key + :returns: Wrapping key that contains the specified static key + :rtype: :class:`aws_encryption_sdk.internal.crypto.WrappingKey` + """ + try: + static_key = self._static_keys[key_id] + except KeyError: + # We fix the static key in order to make the test deterministic + # In practice, you should get this key from a secure key management system such as an HSM. + static_key = PerfTestUtils.DEFAULT_RSA_PRIVATE_KEY + self._static_keys[key_id] = static_key + return WrappingKey( + wrapping_algorithm=WrappingAlgorithm.RSA_OAEP_SHA256_MGF1, + wrapping_key=static_key, + wrapping_key_type=EncryptionKeyType.PRIVATE, + ) + + +def create_key_provider(): + """Demonstrate how to create a Raw RSA master key-provider. + + Usage: create_key_provider() + """ + # Create a Raw RSA master key-provider. + + # The Key ID field in the JceMasterKey and RawMasterKey is equivalent to key name in the Raw keyrings + key_id = "My 4096-bit RSA wrapping key" + key_provider = StaticRandomMasterKeyProvider() + key_provider.add_master_key(key_id) + + return key_provider + + +def encrypt_using_key_provider( + plaintext_data: bytes, + key_provider: aws_encryption_sdk.key_providers.base.MasterKeyProvider +): + """Demonstrate how to encrypt plaintext data using a Raw RSA master key-provider. + + Usage: encrypt_using_key_provider(plaintext_data, key_provider) + :param plaintext_data: plaintext data you want to encrypt + :type: bytes + :param key_provider: Master key provider to use for encryption. + :type key_provider: aws_encryption_sdk.key_providers.base.MasterKeyProvider + """ + client = aws_encryption_sdk.EncryptionSDKClient() + + ciphertext_data, _ = client.encrypt( + source=plaintext_data, + key_provider=key_provider + ) + + return ciphertext_data + + +def decrypt_using_key_provider( + ciphertext_data: bytes, + key_provider: aws_encryption_sdk.key_providers.base.MasterKeyProvider +): + """Demonstrate how to decrypt ciphertext data using a Raw RSA master key-provider. + + Usage: decrypt_using_key_provider(ciphertext_data, key_provider) + :param ciphertext_data: ciphertext data you want to decrypt + :type: bytes + :param key_provider: Master key provider to use for decryption. + :type key_provider: aws_encryption_sdk.key_providers.base.MasterKeyProvider + """ + client = aws_encryption_sdk.EncryptionSDKClient() + + decrypted_plaintext_data, _ = client.decrypt( + source=ciphertext_data, + key_provider=key_provider + ) + + return decrypted_plaintext_data diff --git a/performance_tests/src/aws_encryption_sdk_performance_tests/utils/__init__.py b/performance_tests/src/aws_encryption_sdk_performance_tests/utils/__init__.py new file mode 100644 index 000000000..120179eda --- /dev/null +++ b/performance_tests/src/aws_encryption_sdk_performance_tests/utils/__init__.py @@ -0,0 +1,3 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +"""Stub module indicator to make linter configuration simpler.""" diff --git a/performance_tests/src/aws_encryption_sdk_performance_tests/utils/util.py b/performance_tests/src/aws_encryption_sdk_performance_tests/utils/util.py new file mode 100644 index 000000000..52914b76a --- /dev/null +++ b/performance_tests/src/aws_encryption_sdk_performance_tests/utils/util.py @@ -0,0 +1,116 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +"""Utility functions for AWS Encryption SDK performance tests.""" + + +class PerfTestUtils: + """Utility functions for AWS Encryption SDK performance tests.""" + DEFAULT_N_ITERS = 100 + DEFAULT_TESTING_N_ITERS = 1 + DEFAULT_FILE_SIZE = 'medium' + DEFAULT_AES_256_STATIC_KEY = \ + b'_\xcf"\x82\x03\x12\x9d\x00\x8a\xed\xaf\xe4\x80\x1d\x00t\xa6P\xac\xb6\xfe\xc5\xf6/{\xe7\xaaO\x01\x13W\x85' + DEFAULT_RSA_PUBLIC_KEY = bytes("-----BEGIN PUBLIC KEY-----\n" + + "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxwWEEtEofjwaoo3WO79D\n" + + "hntoPf2APlY5yzlqm6ZvMyaazlwetkAzLSn5GB4hjKZaf043BfADJEdwXMHn8/UN\n" + + "up0BfUj8PfGn/b8cL78CTnvFZd/7WxQh6tUnfLX7BMiccHMb9OHhRy5PrTSuj6Um\n" + + "wwhBadL+Lc23DGl2cyN9SjGuYWWQ1IHGFA4/2EQr+Ez4LpebZqwXgv0iLuApte1q\n" + + "vGl6zOhByxi1N/ORVEscLT82+L+F3STgeTYA1CaoLFQ0y9ybx+7UUfEfKxhGoGEO\n" + + "XEOTuRBdLE2Jm8xaBODLqfiXr0z62VhTpRs4CYYTGHTLFCJHqeH7R2fwvwoG1nIg\n" + + "QzWSyyapK7d5MLn3rF3ManjZhvlyHK1wqa7nWVpo+jq1Py+HWLAtU8FY0br6wnOR\n" + + "3jjPGk0N4//iDnxNN+kpDxFnHEvxe3eJKWnbw0GR9+BGj32O+wRMtGyfRTzkoD/E\n" + + "EqIRlDzdtYCAtFW0HUsdQwL+ssDjEQ0+lqvEQrwTU1WBZiBQhEmzksAowHAcNIT+\n" + + "Fz7mvIlpEETNOQbsJkoXdEkhJXljh5UYmH1cB5al1MJf/5ea5Xb2HfH5WkMy4+eS\n" + + "V68V+tXv3ZthTe2bCk9rQTH9FWKLIYJyZfv8WAIxSWEEsyk5b+7WUGmvtm/nPJ4Z\n" + + "RfzkXoBJqJiSiPYCM0+jG4sCAwEAAQ==\n" + + "-----END PUBLIC KEY-----\n", 'utf-8') + + DEFAULT_RSA_PRIVATE_KEY = bytes("-----BEGIN PRIVATE KEY-----\n" + + "MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQDHBYQS0Sh+PBqi\n" + + "jdY7v0OGe2g9/YA+VjnLOWqbpm8zJprOXB62QDMtKfkYHiGMplp/TjcF8AMkR3Bc\n" + + "wefz9Q26nQF9SPw98af9vxwvvwJOe8Vl3/tbFCHq1Sd8tfsEyJxwcxv04eFHLk+t\n" + + "NK6PpSbDCEFp0v4tzbcMaXZzI31KMa5hZZDUgcYUDj/YRCv4TPgul5tmrBeC/SIu\n" + + "4Cm17Wq8aXrM6EHLGLU385FUSxwtPzb4v4XdJOB5NgDUJqgsVDTL3JvH7tRR8R8r\n" + + "GEagYQ5cQ5O5EF0sTYmbzFoE4Mup+JevTPrZWFOlGzgJhhMYdMsUIkep4ftHZ/C/\n" + + "CgbWciBDNZLLJqkrt3kwufesXcxqeNmG+XIcrXCprudZWmj6OrU/L4dYsC1TwVjR\n" + + "uvrCc5HeOM8aTQ3j/+IOfE036SkPEWccS/F7d4kpadvDQZH34EaPfY77BEy0bJ9F\n" + + "POSgP8QSohGUPN21gIC0VbQdSx1DAv6ywOMRDT6Wq8RCvBNTVYFmIFCESbOSwCjA\n" + + "cBw0hP4XPua8iWkQRM05BuwmShd0SSEleWOHlRiYfVwHlqXUwl//l5rldvYd8fla\n" + + "QzLj55JXrxX61e/dm2FN7ZsKT2tBMf0VYoshgnJl+/xYAjFJYQSzKTlv7tZQaa+2\n" + + "b+c8nhlF/ORegEmomJKI9gIzT6MbiwIDAQABAoICAAi9ysfCzQsCW88g+LRmGbKp\n" + + "7/GtFTlnsyEkc/TDMiYmf20p6aVqm3TT3596D1IsqlPmHQ+TM6gfxSUl1SjHbiNw\n" + + "qvSURJP57b186+GC+7hzwj9Pv6wH7ddxJktZeN2EbC6aN7OhSjJEq/Y5FqOzhsjR\n" + + "L4JU5Joha3VNmojDGcks9nJLsjlLO+Z8m7xFfkLpKottWEOBsoSr1pkFen+FnocJ\n" + + "AP5IAz/G5YrAFXWE2Qd5u9HgI6KLcJqSTyYCTqenySvdFDCLYmL4+rv7VHrN2IIf\n" + + "67iYqeb8vtsLdja5ouhjxVHLSUdLlFzvnZ35eBQ+aP8I5GnnRZCk1ZOmfpdjqtwE\n" + + "4mQRJU44DtGH/aySgQEAjn5BAxjrflSBpgAJs8HxTIoGXEEtGgJQeJcvSxv/1fTy\n" + + "EJSmwzepxDT1kAK0BPEllSHNLlHTEeJ8FMCGaEofDXPvJsJP/UvWxGmyRQXtG68m\n" + + "WAy27OsAQ2z6Iqn2829lUnJERjtFUHJDu5ZlJHRPz6d7FTbmI5jFOGGTDWKtHqFI\n" + + "88JZTwby55KyYLwDyxbqcDrRSOtzZ4N0rV2tLIMRoMDpjhJ8CopuxuQyxeuP3/7V\n" + + "tcW4IbNTqEDKL4TFZkZhb+govAvFAkRFjBWu7kZpSEGNVvR+O1pTgXxWsfaAb+3K\n" + + "EZ0lXelzaGCMCbwysAhxAoIBAQD+AfzgIva7GelSKujRO8rlhtPxoVNTMDbRo9QX\n" + + "NtztLHvrxyaZqM5nqf4rMjrbU7vPdT5Fn/3/iupaBkZk8IqqdKpdmgi+Pr+aFvOB\n" + + "LU2blEY8zWZCOwYerrwEPbQKblLdkIhDvOGpx1g4JuAlqIqJWW/RvMODf9Makwyq\n" + + "fxkG+y2Cr8TIsM3jKXprOkgeE7sB97r2OvkSuL/xP2cedCt0dI1vnk2QvUWw6af4\n" + + "Fs4xzqntS3KG3PHM9Jhljadm6da3cFnQxTIYpS0qT+Dv07NnTn1Ysjb2iCXEjvW2\n" + + "vZEjrcLO4dWfZXVIXAjKhG+e/MbCcjEmbhd480SvDjImzk47AoIBAQDIlR+afYw+\n" + + "UHaaQJiqnkY8E/ju4emgwVDZN3QJGEQS1q+HrCM0QAD410cwEBiyhuciYN27lEfU\n" + + "3NXNb4TKYLN9u/Alj0Em+UFN/cPdUEvgrqQXS5E5GWOX3ehG3LYI/a4n6nlo/zdu\n" + + "GSqHU93i8PoKweQFS23oCqnCkH5xBRcyvC3J/T4G/fl8FrnoVn9HLs3vM0gYMZSl\n" + + "Ej2XZJXbitpqS3QyK51ULePVwaC3Zjot3YxsAzpdcSG1/6VNj1QWr9KAr8YdXTu7\n" + + "VcStCElDksVbfMgYahpBYlU4xipPA101ll1KPom1ECI/F6ku5b2H2vnewy2TNzsY\n" + + "QX0R4NFofQLxAoIBAG2af/pbO+naMXKSL2nxighmmFfATAsuV8k4DxGBS+1Pb516\n" + + "jq5pR781fAY5o2n2hKjtJ1S1x80XrS3xXTi7Dqqkssq256TnwJeF5cbMvJswbOpZ\n" + + "mxFjFK3yqhCOa3zAxCL09cd83kb7TJbWN4woYLcJj5WKBTdd1cK2xxVeyHbZtXaZ\n" + + "z6jlmcG2qStRt8K6sswTkGolYkpwy+oWeLGMYR/cFxed0ExvT34aJK+Jb6nQSkSp\n" + + "dJ67Ad91f7j6WcyvhEYdRbQvEwHNbGLAmwgBan1eQfoe1Famwt1A7sfOnq0tkkzg\n" + + "5+PizKvPgr+YS+3nlwBac9joUlqPZgi/cGaMSPcCggEBALbTLZ4sJyM5RhFtJXoG\n" + + "j6/86F4cbk1HRwDmSY5snsepBQ8duGzMldY6qrlFQq2expgQQKrUCfEcZIg+yIOK\n" + + "RrApGEez3ke+02ZaEifsI20k4Y4WI8UuvhdTfX7xd76UMyRQ1N7+GTDyIVB+AfXz\n" + + "fYVGmya0TPY+meMsvwMXB8EHwpikid/nqHoRYNxD0vk30R7g2CqtLnaTPK58URdt\n" + + "5Y0TP1LnbBypQ0y3k1z3AbqCgJaHDrDTCE4SOUKLjLKtCaqgDG0BaQtkrsKkldrQ\n" + + "sbCk+OE//LRyA4mfHjssrs3EQz4D6JKvpPdrApsrbmihEDWaIzVXFzcRogUkrNqX\n" + + "b5ECggEBAKGW7doJEm0MjyvrJj/Tj4Zx3S8UjMgheBEIUZtMjewtNL0pn70O2AxN\n" + + "aEa4zHaNS0yTgMdbObImzYgat+asJbmFcv0UJy/e4CN+rrZlCHW2D9v9U+O0wKLB\n" + + "e5AmmFwaT/vVIy4gmBTcKGxV90ZF799gmKSoHAlrgjPFSRB/WcJsMwsGEyXl/C4Z\n" + + "4/xCqJgr0VJvuwrCiWf1QKn9AHuytit27E2R52n4FjU5nJ+CJEQqU1XDgF0x+txw\n" + + "PXUuRjOxKO6MzldzqJSUrTir8uqCwBIR9x9GOrGDp//ZbRw2TK4EbkyjNYO7KtOF\n" + + "A/DHJmMI5bKETJyj1GhBE9LqypAI1Bo=\n" + + "-----END PRIVATE KEY-----\n", "utf-8") + + DEFAULT_ENCRYPTION_CONTEXT = { + "tenant": "TenantA", + "encryption": "context", + "is not": "secret", + "but adds": "useful metadata", + "that can help you": "be confident that", + "the data you are handling": "is what you think it is", + } + + DEFAULT_BRANCH_KEY_ID_A = 'a52dfaad-7dbd-4430-a1fd-abaa5299da07' + + DEFAULT_BRANCH_KEY_ID_B = '8ba79cef-581c-4125-9292-b057a29d42d7' + + @staticmethod + def read_file(filename): + """Returns the contents of the file.""" + with open(filename, 'rb') as file: + return file.read() + + @staticmethod + def get_rsa_key_from_file(filename): + """Returns the RSA key""" + with open(filename, "r", encoding='utf-8') as f: + key = f.read() + + # Convert the key from a string to bytes + key = bytes(key, 'utf-8') + + return key + + @staticmethod + def write_time_list_to_csv(time_list, filename): + """Writes the time list to a CSV file.""" + with open(filename + '.csv', 'w', encoding='utf-8') as myfile: + for time in time_list: + myfile.write(str(time) + '\n') diff --git a/performance_tests/test/keyrings/__init__.py b/performance_tests/test/keyrings/__init__.py new file mode 100644 index 000000000..120179eda --- /dev/null +++ b/performance_tests/test/keyrings/__init__.py @@ -0,0 +1,3 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +"""Stub module indicator to make linter configuration simpler.""" diff --git a/performance_tests/test/keyrings/test_aws_kms_keyring.py b/performance_tests/test/keyrings/test_aws_kms_keyring.py new file mode 100644 index 000000000..950a2a82e --- /dev/null +++ b/performance_tests/test/keyrings/test_aws_kms_keyring.py @@ -0,0 +1,206 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +"""This is a performance test for creating the AWS KMS keyring.""" + +import os +import time + +import click +import click.testing +import pytest +from tqdm import tqdm + +from aws_encryption_sdk_performance_tests.keyrings.aws_kms_keyring import ( + create_keyring, + create_keyring_given_kms_client, + create_kms_client, + decrypt_using_keyring, + encrypt_using_keyring, +) +from aws_encryption_sdk_performance_tests.utils.util import PerfTestUtils + +MODULE_ABS_PATH = os.path.abspath(__file__) + + +@click.group() +def create_kms_keyring(): + """Click group helper function""" + + +@create_kms_keyring.command() +@click.option('--kms_key_id', + default='arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f') +@click.option('--n_iters', + default=PerfTestUtils.DEFAULT_N_ITERS) +@click.option('--output_file', + default='/'.join(MODULE_ABS_PATH.split("/")[:-3]) + '/results/kms_keyring_create') +def create( + kms_key_id: str, + n_iters: int, + output_file: str +): + """Performance test for the create_keyring function.""" + time_list = [] + for _ in tqdm(range(n_iters)): + curr_time = time.time() + + create_keyring(kms_key_id) + + # calculate elapsed time in milliseconds + elapsed_time = (time.time() - curr_time) * 1000 + time_list.append(elapsed_time) + PerfTestUtils.write_time_list_to_csv(time_list, output_file) + + +@click.group() +def create_kms_keyring_given_kms_client(): + """Click group helper function""" + + +@create_kms_keyring_given_kms_client.command() +@click.option('--kms_key_id', + default='arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f') +@click.option('--n_iters', + default=PerfTestUtils.DEFAULT_N_ITERS) +@click.option('--output_file', + default='/'.join(MODULE_ABS_PATH.split("/")[:-3]) + '/results/kms_keyring_create_given_kms_client') +def create_given_kms_client( + kms_key_id: str, + n_iters: int, + output_file: str +): + """Performance test for the create_keyring function.""" + kms_client = create_kms_client() + time_list = [] + for _ in tqdm(range(n_iters)): + curr_time = time.time() + + create_keyring_given_kms_client(kms_key_id, kms_client) + + # calculate elapsed time in milliseconds + elapsed_time = (time.time() - curr_time) * 1000 + time_list.append(elapsed_time) + + PerfTestUtils.write_time_list_to_csv(time_list, output_file) + + +@click.group() +def encrypt_kms_keyring(): + """Click group helper function""" + + +@encrypt_kms_keyring.command() +@click.option('--plaintext_data_filename', + default='/'.join(MODULE_ABS_PATH.split("/")[:-2]) + '/resources/plaintext/plaintext-data-' + + PerfTestUtils.DEFAULT_FILE_SIZE + '.dat') +@click.option('--kms_key_id', + default='arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f') +@click.option('--n_iters', + default=PerfTestUtils.DEFAULT_N_ITERS) +@click.option('--output_file', + default='/'.join(MODULE_ABS_PATH.split("/")[:-3]) + '/results/kms_keyring_encrypt') +def encrypt( + plaintext_data_filename: str, + kms_key_id: str, + n_iters: int, + output_file: str +): + """Performance test for the encrypt_using_keyring function.""" + plaintext_data = PerfTestUtils.read_file(plaintext_data_filename) + + keyring = create_keyring(kms_key_id) + time_list = [] + + for _ in tqdm(range(n_iters)): + curr_time = time.time() + + encrypt_using_keyring(plaintext_data, keyring) + + # calculate elapsed time in milliseconds + elapsed_time = (time.time() - curr_time) * 1000 + time_list.append(elapsed_time) + + PerfTestUtils.write_time_list_to_csv(time_list, output_file) + + +@click.group() +def decrypt_kms_keyring(): + """Click group helper function""" + + +@decrypt_kms_keyring.command() +@click.option('--ciphertext_data_filename', + default='/'.join(MODULE_ABS_PATH.split("/")[:-2]) + '/resources/ciphertext/kms/ciphertext-data-' + + PerfTestUtils.DEFAULT_FILE_SIZE + '.ct') +@click.option('--kms_key_id', + default='arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f') +@click.option('--n_iters', + default=PerfTestUtils.DEFAULT_N_ITERS) +@click.option('--output_file', + default='/'.join(MODULE_ABS_PATH.split("/")[:-3]) + '/results/kms_keyring_decrypt') +def decrypt( + ciphertext_data_filename: str, + kms_key_id: str, + n_iters: int, + output_file: str +): + """Performance test for the decrypt_using_keyring function.""" + ciphertext_data = PerfTestUtils.read_file(ciphertext_data_filename) + + keyring = create_keyring(kms_key_id) + time_list = [] + + for _ in tqdm(range(n_iters)): + curr_time = time.time() + + decrypt_using_keyring(ciphertext_data, keyring) + + # calculate elapsed time in milliseconds + elapsed_time = (time.time() - curr_time) * 1000 + time_list.append(elapsed_time) + + PerfTestUtils.write_time_list_to_csv(time_list, output_file) + + +kms_keyring_test = click.CommandCollection(sources=[create_kms_keyring, + create_kms_keyring_given_kms_client, + encrypt_kms_keyring, + decrypt_kms_keyring]) + + +@pytest.fixture +def runner(): + """Click runner""" + return click.testing.CliRunner() + + +def test_create(runner): + """Test the create_keyring function""" + result = runner.invoke(create_kms_keyring.commands['create'], + ['--n_iters', PerfTestUtils.DEFAULT_TESTING_N_ITERS]) + assert result.exit_code == 0 + + +def test_create_given_kms_client(runner): + """Test the create_keyring_given_kms_client function""" + result = runner.invoke(create_kms_keyring_given_kms_client.commands['create-given-kms-client'], + ['--n_iters', PerfTestUtils.DEFAULT_TESTING_N_ITERS]) + assert result.exit_code == 0 + + +def test_encrypt(runner): + """Test the encrypt_using_keyring function""" + result = runner.invoke(encrypt_kms_keyring.commands['encrypt'], + ['--n_iters', PerfTestUtils.DEFAULT_TESTING_N_ITERS]) + assert result.exit_code == 0 + + +def test_decrypt(runner): + """Test the decrypt_using_keyring function""" + result = runner.invoke(decrypt_kms_keyring.commands['decrypt'], + ['--n_iters', PerfTestUtils.DEFAULT_TESTING_N_ITERS]) + assert result.exit_code == 0 + + +if __name__ == "__main__": + kms_keyring_test() diff --git a/performance_tests/test/keyrings/test_raw_aes_keyring.py b/performance_tests/test/keyrings/test_raw_aes_keyring.py new file mode 100644 index 000000000..1e1da428a --- /dev/null +++ b/performance_tests/test/keyrings/test_raw_aes_keyring.py @@ -0,0 +1,156 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +"""This is a performance test for creating the Raw AES keyring.""" + +import os +import time + +import click +import click.testing +import pytest +from tqdm import tqdm + +from aws_encryption_sdk_performance_tests.keyrings.raw_aes_keyring import ( + create_keyring, + decrypt_using_keyring, + encrypt_using_keyring, +) +from aws_encryption_sdk_performance_tests.utils.util import PerfTestUtils + +MODULE_ABS_PATH = os.path.abspath(__file__) + + +@click.group() +def create_raw_aes_keyring(): + """Click group helper function""" + + +@create_raw_aes_keyring.command() +@click.option('--n_iters', + default=PerfTestUtils.DEFAULT_N_ITERS) +@click.option('--output_file', + default='/'.join(MODULE_ABS_PATH.split("/")[:-3]) + '/results/raw_aes_keyring_create') +def create( + n_iters: int, + output_file: str +): + """Performance test for the create_keyring function.""" + time_list = [] + for _ in tqdm(range(n_iters)): + curr_time = time.time() + + create_keyring() + + # calculate elapsed time in milliseconds + elapsed_time = (time.time() - curr_time) * 1000 + time_list.append(elapsed_time) + + PerfTestUtils.write_time_list_to_csv(time_list, output_file) + + +@click.group() +def encrypt_raw_aes_keyring(): + """Click group helper function""" + + +@encrypt_raw_aes_keyring.command() +@click.option('--plaintext_data_filename', + default='/'.join(MODULE_ABS_PATH.split("/")[:-2]) + '/resources/plaintext/plaintext-data-' + + PerfTestUtils.DEFAULT_FILE_SIZE + '.dat') +@click.option('--n_iters', + default=PerfTestUtils.DEFAULT_N_ITERS) +@click.option('--output_file', + default='/'.join(MODULE_ABS_PATH.split("/")[:-3]) + '/results/raw_aes_keyring_encrypt') +def encrypt( + plaintext_data_filename: str, + n_iters: int, + output_file: str +): + """Performance test for the encrypt_using_keyring function.""" + plaintext_data = PerfTestUtils.read_file(plaintext_data_filename) + + keyring = create_keyring() + time_list = [] + + for _ in tqdm(range(n_iters)): + curr_time = time.time() + + encrypt_using_keyring(plaintext_data, keyring) + + # calculate elapsed time in milliseconds + elapsed_time = (time.time() - curr_time) * 1000 + time_list.append(elapsed_time) + + PerfTestUtils.write_time_list_to_csv(time_list, output_file) + + +@click.group() +def decrypt_raw_aes_keyring(): + """Click group helper function""" + + +@decrypt_raw_aes_keyring.command() +@click.option('--ciphertext_data_filename', + default='/'.join(MODULE_ABS_PATH.split("/")[:-2]) + '/resources/ciphertext/raw_aes/ciphertext-data-' + + PerfTestUtils.DEFAULT_FILE_SIZE + '.ct') +@click.option('--n_iters', + default=PerfTestUtils.DEFAULT_N_ITERS) +@click.option('--output_file', + default='/'.join(MODULE_ABS_PATH.split("/")[:-3]) + '/results/raw_aes_keyring_decrypt') +def decrypt( + ciphertext_data_filename: str, + n_iters: int, + output_file: str +): + """Performance test for the decrypt_using_keyring function.""" + ciphertext_data = PerfTestUtils.read_file(ciphertext_data_filename) + + keyring = create_keyring() + time_list = [] + + for _ in tqdm(range(n_iters)): + curr_time = time.time() + + decrypt_using_keyring(ciphertext_data, keyring) + + # calculate elapsed time in milliseconds + elapsed_time = (time.time() - curr_time) * 1000 + time_list.append(elapsed_time) + + PerfTestUtils.write_time_list_to_csv(time_list, output_file) + + +raw_aes_keyring_test = click.CommandCollection(sources=[create_raw_aes_keyring, + encrypt_raw_aes_keyring, + decrypt_raw_aes_keyring]) + + +@pytest.fixture +def runner(): + """Click runner""" + return click.testing.CliRunner() + + +def test_create(runner): + """Test the create_keyring function""" + result = runner.invoke(create_raw_aes_keyring.commands['create'], + ['--n_iters', PerfTestUtils.DEFAULT_TESTING_N_ITERS]) + assert result.exit_code == 0 + + +def test_encrypt(runner): + """Test the encrypt_using_keyring function""" + result = runner.invoke(encrypt_raw_aes_keyring.commands['encrypt'], + ['--n_iters', PerfTestUtils.DEFAULT_TESTING_N_ITERS]) + assert result.exit_code == 0 + + +def test_decrypt(runner): + """Test the decrypt_using_keyring function""" + result = runner.invoke(decrypt_raw_aes_keyring.commands['decrypt'], + ['--n_iters', PerfTestUtils.DEFAULT_TESTING_N_ITERS]) + assert result.exit_code == 0 + + +if __name__ == "__main__": + raw_aes_keyring_test() diff --git a/performance_tests/test/keyrings/test_raw_rsa_keyring.py b/performance_tests/test/keyrings/test_raw_rsa_keyring.py new file mode 100644 index 000000000..476701ac0 --- /dev/null +++ b/performance_tests/test/keyrings/test_raw_rsa_keyring.py @@ -0,0 +1,163 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +"""This is a performance test for creating the Raw RSA keyring.""" + +import os +import time + +import click +import click.testing +import pytest +from tqdm import tqdm + +from aws_encryption_sdk_performance_tests.keyrings.raw_rsa_keyring import ( + create_keyring, + decrypt_using_keyring, + encrypt_using_keyring, +) +from aws_encryption_sdk_performance_tests.utils.util import PerfTestUtils + +MODULE_ABS_PATH = os.path.abspath(__file__) + + +@click.group() +def create_raw_rsa_keyring(): + """Click group helper function""" + + +@create_raw_rsa_keyring.command() +@click.option('--n_iters', + default=PerfTestUtils.DEFAULT_N_ITERS) +@click.option('--output_file', + default='/'.join(MODULE_ABS_PATH.split("/")[:-3]) + '/results/raw_rsa_keyring_create') +def create( + n_iters: int, + output_file: str +): + """Performance test for the create_keyring function.""" + public_key = PerfTestUtils.DEFAULT_RSA_PUBLIC_KEY + private_key = PerfTestUtils.DEFAULT_RSA_PRIVATE_KEY + + time_list = [] + for _ in tqdm(range(n_iters)): + curr_time = time.time() + + create_keyring(public_key, private_key) + + # calculate elapsed time in milliseconds + elapsed_time = (time.time() - curr_time) * 1000 + time_list.append(elapsed_time) + + PerfTestUtils.write_time_list_to_csv(time_list, output_file) + + +@click.group() +def encrypt_raw_rsa_keyring(): + """Click group helper function""" + + +@encrypt_raw_rsa_keyring.command() +@click.option('--plaintext_data_filename', + default='/'.join(MODULE_ABS_PATH.split("/")[:-2]) + '/resources/plaintext/plaintext-data-' + + PerfTestUtils.DEFAULT_FILE_SIZE + '.dat') +@click.option('--n_iters', + default=PerfTestUtils.DEFAULT_N_ITERS) +@click.option('--output_file', + default='/'.join(MODULE_ABS_PATH.split("/")[:-3]) + '/results/raw_rsa_keyring_encrypt') +def encrypt( + plaintext_data_filename: str, + n_iters: int, + output_file: str +): + """Performance test for the encrypt_using_keyring function.""" + public_key = PerfTestUtils.DEFAULT_RSA_PUBLIC_KEY + private_key = PerfTestUtils.DEFAULT_RSA_PRIVATE_KEY + plaintext_data = PerfTestUtils.read_file(plaintext_data_filename) + + keyring = create_keyring(public_key, private_key) + time_list = [] + + for _ in tqdm(range(n_iters)): + curr_time = time.time() + + encrypt_using_keyring(plaintext_data, keyring) + + # calculate elapsed time in milliseconds + elapsed_time = (time.time() - curr_time) * 1000 + time_list.append(elapsed_time) + + PerfTestUtils.write_time_list_to_csv(time_list, output_file) + + +@click.group() +def decrypt_raw_rsa_keyring(): + """Click group helper function""" + + +@decrypt_raw_rsa_keyring.command() +@click.option('--ciphertext_data_filename', + default='/'.join(MODULE_ABS_PATH.split("/")[:-2]) + '/resources/ciphertext/raw_rsa/ciphertext-data-' + + PerfTestUtils.DEFAULT_FILE_SIZE + '.ct') +@click.option('--n_iters', + default=PerfTestUtils.DEFAULT_N_ITERS) +@click.option('--output_file', + default='/'.join(MODULE_ABS_PATH.split("/")[:-3]) + '/results/raw_rsa_keyring_decrypt') +def decrypt( + ciphertext_data_filename: str, + n_iters: int, + output_file: str +): + """Performance test for the decrypt_using_keyring function.""" + public_key = PerfTestUtils.DEFAULT_RSA_PUBLIC_KEY + private_key = PerfTestUtils.DEFAULT_RSA_PRIVATE_KEY + ciphertext_data = PerfTestUtils.read_file(ciphertext_data_filename) + + keyring = create_keyring(public_key, private_key) + time_list = [] + + for _ in tqdm(range(n_iters)): + curr_time = time.time() + + decrypt_using_keyring(ciphertext_data, keyring) + + # calculate elapsed time in milliseconds + elapsed_time = (time.time() - curr_time) * 1000 + time_list.append(elapsed_time) + + PerfTestUtils.write_time_list_to_csv(time_list, output_file) + + +raw_rsa_keyring_test = click.CommandCollection(sources=[create_raw_rsa_keyring, + encrypt_raw_rsa_keyring, + decrypt_raw_rsa_keyring]) + + +@pytest.fixture +def runner(): + """Click runner""" + return click.testing.CliRunner() + + +def test_create(runner): + """Test the create_keyring function""" + result = runner.invoke(create_raw_rsa_keyring.commands['create'], + ['--n_iters', PerfTestUtils.DEFAULT_TESTING_N_ITERS]) + assert result.exit_code == 0 + + +def test_encrypt(runner): + """Test the encrypt_using_keyring function""" + result = runner.invoke(encrypt_raw_rsa_keyring.commands['encrypt'], + ['--n_iters', PerfTestUtils.DEFAULT_TESTING_N_ITERS]) + assert result.exit_code == 0 + + +def test_decrypt(runner): + """Test the decrypt_using_keyring function""" + result = runner.invoke(decrypt_raw_rsa_keyring.commands['decrypt'], + ['--n_iters', PerfTestUtils.DEFAULT_TESTING_N_ITERS]) + assert result.exit_code == 0 + + +if __name__ == "__main__": + raw_rsa_keyring_test() diff --git a/performance_tests/test/master_key_providers/__init__.py b/performance_tests/test/master_key_providers/__init__.py new file mode 100644 index 000000000..120179eda --- /dev/null +++ b/performance_tests/test/master_key_providers/__init__.py @@ -0,0 +1,3 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +"""Stub module indicator to make linter configuration simpler.""" diff --git a/performance_tests/test/master_key_providers/test_aws_kms_master_key_provider.py b/performance_tests/test/master_key_providers/test_aws_kms_master_key_provider.py new file mode 100644 index 000000000..b869245b5 --- /dev/null +++ b/performance_tests/test/master_key_providers/test_aws_kms_master_key_provider.py @@ -0,0 +1,165 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +"""This is a performance test for creating the AWS KMS Master key-provider.""" + +import os +import time + +import click +import click.testing +import pytest +from tqdm import tqdm + +from aws_encryption_sdk_performance_tests.master_key_providers.aws_kms_master_key_provider import ( + create_key_provider, + decrypt_using_key_provider, + encrypt_using_key_provider, +) +from aws_encryption_sdk_performance_tests.utils.util import PerfTestUtils + +MODULE_ABS_PATH = os.path.abspath(__file__) + + +@click.group() +def create_kms_key_provider(): + """Click group helper function""" + + +@create_kms_key_provider.command() +@click.option('--kms_key_id', + default='arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f') +@click.option('--n_iters', + default=PerfTestUtils.DEFAULT_N_ITERS) +@click.option('--output_file', + default='/'.join(MODULE_ABS_PATH.split("/")[:-3]) + '/results/kms_key_provider_create') +def create( + kms_key_id: str, + n_iters: int, + output_file: str +): + """Performance test for the create_key_provider function.""" + time_list = [] + for _ in tqdm(range(n_iters)): + curr_time = time.time() + + create_key_provider(kms_key_id) + + # calculate elapsed time in milliseconds + elapsed_time = (time.time() - curr_time) * 1000 + time_list.append(elapsed_time) + + PerfTestUtils.write_time_list_to_csv(time_list, output_file) + + +@click.group() +def encrypt_kms_key_provider(): + """Click group helper function""" + + +@encrypt_kms_key_provider.command() +@click.option('--plaintext_data_filename', + default='/'.join(MODULE_ABS_PATH.split("/")[:-2]) + '/resources/plaintext/plaintext-data-' + + PerfTestUtils.DEFAULT_FILE_SIZE + '.dat') +@click.option('--kms_key_id', + default='arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f') +@click.option('--n_iters', + default=PerfTestUtils.DEFAULT_N_ITERS) +@click.option('--output_file', + default='/'.join(MODULE_ABS_PATH.split("/")[:-3]) + '/results/kms_key_provider_encrypt') +def encrypt( + plaintext_data_filename: str, + kms_key_id: str, + n_iters: int, + output_file: str +): + """Performance test for the encrypt_using_key_provider function.""" + plaintext_data = PerfTestUtils.read_file(plaintext_data_filename) + + key_provider = create_key_provider(kms_key_id) + time_list = [] + + for _ in tqdm(range(n_iters)): + curr_time = time.time() + + encrypt_using_key_provider(plaintext_data, key_provider) + + # calculate elapsed time in milliseconds + elapsed_time = (time.time() - curr_time) * 1000 + time_list.append(elapsed_time) + + PerfTestUtils.write_time_list_to_csv(time_list, output_file) + + +@click.group() +def decrypt_kms_key_provider(): + """Click group helper function""" + + +@decrypt_kms_key_provider.command() +@click.option('--ciphertext_data_filename', + default='/'.join(MODULE_ABS_PATH.split("/")[:-2]) + '/resources/ciphertext/kms/ciphertext-data-' + + PerfTestUtils.DEFAULT_FILE_SIZE + '.ct') +@click.option('--kms_key_id', + default='arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f') +@click.option('--n_iters', + default=PerfTestUtils.DEFAULT_N_ITERS) +@click.option('--output_file', + default='/'.join(MODULE_ABS_PATH.split("/")[:-3]) + '/results/kms_key_provider_decrypt') +def decrypt( + ciphertext_data_filename: str, + kms_key_id: str, + n_iters: int, + output_file: str +): + """Performance test for the decrypt_using_key_provider function.""" + ciphertext_data = PerfTestUtils.read_file(ciphertext_data_filename) + + key_provider = create_key_provider(kms_key_id) + time_list = [] + + for _ in tqdm(range(n_iters)): + curr_time = time.time() + + decrypt_using_key_provider(ciphertext_data, key_provider) + + # calculate elapsed time in milliseconds + elapsed_time = (time.time() - curr_time) * 1000 + time_list.append(elapsed_time) + + PerfTestUtils.write_time_list_to_csv(time_list, output_file) + + +kms_key_provider_test = click.CommandCollection(sources=[create_kms_key_provider, + encrypt_kms_key_provider, + decrypt_kms_key_provider]) + + +@pytest.fixture +def runner(): + """Click runner""" + return click.testing.CliRunner() + + +def test_create(runner): + """Test the create_key_provider function""" + result = runner.invoke(create_kms_key_provider.commands['create'], + ['--n_iters', PerfTestUtils.DEFAULT_TESTING_N_ITERS]) + assert result.exit_code == 0 + + +def test_encrypt(runner): + """Test the encrypt_using_key_provider function""" + result = runner.invoke(encrypt_kms_key_provider.commands['encrypt'], + ['--n_iters', PerfTestUtils.DEFAULT_TESTING_N_ITERS]) + assert result.exit_code == 0 + + +def test_decrypt(runner): + """Test the decrypt_using_key_provider function""" + result = runner.invoke(decrypt_kms_key_provider.commands['decrypt'], + ['--n_iters', PerfTestUtils.DEFAULT_TESTING_N_ITERS]) + assert result.exit_code == 0 + + +if __name__ == "__main__": + kms_key_provider_test() diff --git a/performance_tests/test/master_key_providers/test_raw_aes_master_key_provider.py b/performance_tests/test/master_key_providers/test_raw_aes_master_key_provider.py new file mode 100644 index 000000000..375eca2ef --- /dev/null +++ b/performance_tests/test/master_key_providers/test_raw_aes_master_key_provider.py @@ -0,0 +1,156 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +"""This is a performance test for creating the Raw AES Master key-provider.""" + +import os +import time + +import click +import click.testing +import pytest +from tqdm import tqdm + +from aws_encryption_sdk_performance_tests.master_key_providers.raw_aes_master_key_provider import ( + create_key_provider, + decrypt_using_key_provider, + encrypt_using_key_provider, +) +from aws_encryption_sdk_performance_tests.utils.util import PerfTestUtils + +MODULE_ABS_PATH = os.path.abspath(__file__) + + +@click.group() +def create_raw_aes_key_provider(): + """Click group helper function""" + + +@create_raw_aes_key_provider.command() +@click.option('--n_iters', + default=PerfTestUtils.DEFAULT_N_ITERS) +@click.option('--output_file', + default='/'.join(MODULE_ABS_PATH.split("/")[:-3]) + '/results/raw_aes_key_provider_create') +def create( + n_iters: int, + output_file: str +): + """Performance test for the create_key_provider function.""" + time_list = [] + for _ in tqdm(range(n_iters)): + curr_time = time.time() + + create_key_provider() + + # calculate elapsed time in milliseconds + elapsed_time = (time.time() - curr_time) * 1000 + time_list.append(elapsed_time) + + PerfTestUtils.write_time_list_to_csv(time_list, output_file) + + +@click.group() +def encrypt_raw_aes_key_provider(): + """Click group helper function""" + + +@encrypt_raw_aes_key_provider.command() +@click.option('--plaintext_data_filename', + default='/'.join(MODULE_ABS_PATH.split("/")[:-2]) + '/resources/plaintext/plaintext-data-' + + PerfTestUtils.DEFAULT_FILE_SIZE + '.dat') +@click.option('--n_iters', + default=PerfTestUtils.DEFAULT_N_ITERS) +@click.option('--output_file', + default='/'.join(MODULE_ABS_PATH.split("/")[:-3]) + '/results/raw_aes_key_provider_encrypt') +def encrypt( + plaintext_data_filename: str, + n_iters: int, + output_file: str +): + """Performance test for the encrypt_using_key_provider function.""" + plaintext_data = PerfTestUtils.read_file(plaintext_data_filename) + + key_provider = create_key_provider() + time_list = [] + + for _ in tqdm(range(n_iters)): + curr_time = time.time() + + encrypt_using_key_provider(plaintext_data, key_provider) + + # calculate elapsed time in milliseconds + elapsed_time = (time.time() - curr_time) * 1000 + time_list.append(elapsed_time) + + PerfTestUtils.write_time_list_to_csv(time_list, output_file) + + +@click.group() +def decrypt_raw_aes_key_provider(): + """Click group helper function""" + + +@decrypt_raw_aes_key_provider.command() +@click.option('--ciphertext_data_filename', + default='/'.join(MODULE_ABS_PATH.split("/")[:-2]) + '/resources/ciphertext/raw_aes/ciphertext-data-' + + PerfTestUtils.DEFAULT_FILE_SIZE + '.ct') +@click.option('--n_iters', + default=PerfTestUtils.DEFAULT_N_ITERS) +@click.option('--output_file', + default='/'.join(MODULE_ABS_PATH.split("/")[:-3]) + '/results/raw_aes_key_provider_decrypt') +def decrypt( + ciphertext_data_filename: str, + n_iters: int, + output_file: str +): + """Performance test for the decrypt_using_key_provider function.""" + ciphertext_data = PerfTestUtils.read_file(ciphertext_data_filename) + + key_provider = create_key_provider() + time_list = [] + + for _ in tqdm(range(n_iters)): + curr_time = time.time() + + decrypt_using_key_provider(ciphertext_data, key_provider) + + # calculate elapsed time in milliseconds + elapsed_time = (time.time() - curr_time) * 1000 + time_list.append(elapsed_time) + + PerfTestUtils.write_time_list_to_csv(time_list, output_file) + + +raw_aes_key_provider_test = click.CommandCollection(sources=[create_raw_aes_key_provider, + encrypt_raw_aes_key_provider, + decrypt_raw_aes_key_provider]) + + +@pytest.fixture +def runner(): + """Click runner""" + return click.testing.CliRunner() + + +def test_create(runner): + """Test the create_key_provider function""" + result = runner.invoke(create_raw_aes_key_provider.commands['create'], + ['--n_iters', PerfTestUtils.DEFAULT_TESTING_N_ITERS]) + assert result.exit_code == 0 + + +def test_encrypt(runner): + """Test the encrypt_using_key_provider function""" + result = runner.invoke(encrypt_raw_aes_key_provider.commands['encrypt'], + ['--n_iters', PerfTestUtils.DEFAULT_TESTING_N_ITERS]) + assert result.exit_code == 0 + + +def test_decrypt(runner): + """Test the decrypt_using_key_provider function""" + result = runner.invoke(decrypt_raw_aes_key_provider.commands['decrypt'], + ['--n_iters', PerfTestUtils.DEFAULT_TESTING_N_ITERS]) + assert result.exit_code == 0 + + +if __name__ == "__main__": + raw_aes_key_provider_test() diff --git a/performance_tests/test/master_key_providers/test_raw_rsa_master_key_provider.py b/performance_tests/test/master_key_providers/test_raw_rsa_master_key_provider.py new file mode 100644 index 000000000..5d6db861a --- /dev/null +++ b/performance_tests/test/master_key_providers/test_raw_rsa_master_key_provider.py @@ -0,0 +1,156 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +"""This is a performance test for creating the Raw RSA Master key-provider.""" + +import os +import time + +import click +import click.testing +import pytest +from tqdm import tqdm + +from aws_encryption_sdk_performance_tests.master_key_providers.raw_rsa_master_key_provider import ( + create_key_provider, + decrypt_using_key_provider, + encrypt_using_key_provider, +) +from aws_encryption_sdk_performance_tests.utils.util import PerfTestUtils + +MODULE_ABS_PATH = os.path.abspath(__file__) + + +@click.group() +def create_raw_rsa_key_provider(): + """Click group helper function""" + + +@create_raw_rsa_key_provider.command() +@click.option('--n_iters', + default=PerfTestUtils.DEFAULT_N_ITERS) +@click.option('--output_file', + default='/'.join(MODULE_ABS_PATH.split("/")[:-3]) + '/results/raw_rsa_key_provider_create') +def create( + n_iters: int, + output_file: str +): + """Performance test for the create_key_provider function.""" + time_list = [] + for _ in tqdm(range(n_iters)): + curr_time = time.time() + + create_key_provider() + + # calculate elapsed time in milliseconds + elapsed_time = (time.time() - curr_time) * 1000 + time_list.append(elapsed_time) + + PerfTestUtils.write_time_list_to_csv(time_list, output_file) + + +@click.group() +def encrypt_raw_rsa_key_provider(): + """Click group helper function""" + + +@encrypt_raw_rsa_key_provider.command() +@click.option('--plaintext_data_filename', + default='/'.join(MODULE_ABS_PATH.split("/")[:-2]) + '/resources/plaintext/plaintext-data-' + + PerfTestUtils.DEFAULT_FILE_SIZE + '.dat') +@click.option('--n_iters', + default=PerfTestUtils.DEFAULT_N_ITERS) +@click.option('--output_file', + default='/'.join(MODULE_ABS_PATH.split("/")[:-3]) + '/results/raw_rsa_key_provider_encrypt') +def encrypt( + plaintext_data_filename: str, + n_iters: int, + output_file: str +): + """Performance test for the encrypt_using_key_provider function.""" + plaintext_data = PerfTestUtils.read_file(plaintext_data_filename) + + key_provider = create_key_provider() + time_list = [] + + for _ in tqdm(range(n_iters)): + curr_time = time.time() + + encrypt_using_key_provider(plaintext_data, key_provider) + + # calculate elapsed time in milliseconds + elapsed_time = (time.time() - curr_time) * 1000 + time_list.append(elapsed_time) + + PerfTestUtils.write_time_list_to_csv(time_list, output_file) + + +@click.group() +def decrypt_raw_rsa_key_provider(): + """Click group helper function""" + + +@decrypt_raw_rsa_key_provider.command() +@click.option('--ciphertext_data_filename', + default='/'.join(MODULE_ABS_PATH.split("/")[:-2]) + '/resources/ciphertext/raw_rsa/ciphertext-data-' + + PerfTestUtils.DEFAULT_FILE_SIZE + '.ct') +@click.option('--n_iters', + default=PerfTestUtils.DEFAULT_N_ITERS) +@click.option('--output_file', + default='/'.join(MODULE_ABS_PATH.split("/")[:-3]) + '/results/raw_rsa_key_provider_decrypt') +def decrypt( + ciphertext_data_filename: str, + n_iters: int, + output_file: str +): + """Performance test for the decrypt_using_key_provider function.""" + ciphertext_data = PerfTestUtils.read_file(ciphertext_data_filename) + + key_provider = create_key_provider() + time_list = [] + + for _ in tqdm(range(n_iters)): + curr_time = time.time() + + decrypt_using_key_provider(ciphertext_data, key_provider) + + # calculate elapsed time in milliseconds + elapsed_time = (time.time() - curr_time) * 1000 + time_list.append(elapsed_time) + + PerfTestUtils.write_time_list_to_csv(time_list, output_file) + + +raw_rsa_key_provider_test = click.CommandCollection(sources=[create_raw_rsa_key_provider, + encrypt_raw_rsa_key_provider, + decrypt_raw_rsa_key_provider]) + + +@pytest.fixture +def runner(): + """Click runner""" + return click.testing.CliRunner() + + +def test_create(runner): + """Test the create_key_provider function""" + result = runner.invoke(create_raw_rsa_key_provider.commands['create'], + ['--n_iters', PerfTestUtils.DEFAULT_TESTING_N_ITERS]) + assert result.exit_code == 0 + + +def test_encrypt(runner): + """Test the encrypt_using_key_provider function""" + result = runner.invoke(encrypt_raw_rsa_key_provider.commands['encrypt'], + ['--n_iters', PerfTestUtils.DEFAULT_TESTING_N_ITERS]) + assert result.exit_code == 0 + + +def test_decrypt(runner): + """Test the decrypt_using_key_provider function""" + result = runner.invoke(decrypt_raw_rsa_key_provider.commands['decrypt'], + ['--n_iters', PerfTestUtils.DEFAULT_TESTING_N_ITERS]) + assert result.exit_code == 0 + + +if __name__ == "__main__": + raw_rsa_key_provider_test() diff --git a/performance_tests/test/resources/__init__.py b/performance_tests/test/resources/__init__.py new file mode 100644 index 000000000..120179eda --- /dev/null +++ b/performance_tests/test/resources/__init__.py @@ -0,0 +1,3 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +"""Stub module indicator to make linter configuration simpler.""" diff --git a/performance_tests/test/resources/ciphertext/kms/ciphertext-data-empty.ct b/performance_tests/test/resources/ciphertext/kms/ciphertext-data-empty.ct new file mode 100644 index 000000000..18f169687 Binary files /dev/null and b/performance_tests/test/resources/ciphertext/kms/ciphertext-data-empty.ct differ diff --git a/performance_tests/test/resources/ciphertext/kms/ciphertext-data-large.ct b/performance_tests/test/resources/ciphertext/kms/ciphertext-data-large.ct new file mode 100644 index 000000000..076926bfb Binary files /dev/null and b/performance_tests/test/resources/ciphertext/kms/ciphertext-data-large.ct differ diff --git a/performance_tests/test/resources/ciphertext/kms/ciphertext-data-medium.ct b/performance_tests/test/resources/ciphertext/kms/ciphertext-data-medium.ct new file mode 100644 index 000000000..a954c7134 Binary files /dev/null and b/performance_tests/test/resources/ciphertext/kms/ciphertext-data-medium.ct differ diff --git a/performance_tests/test/resources/ciphertext/kms/ciphertext-data-small.ct b/performance_tests/test/resources/ciphertext/kms/ciphertext-data-small.ct new file mode 100644 index 000000000..473e914e6 Binary files /dev/null and b/performance_tests/test/resources/ciphertext/kms/ciphertext-data-small.ct differ diff --git a/performance_tests/test/resources/ciphertext/raw_aes/ciphertext-data-empty.ct b/performance_tests/test/resources/ciphertext/raw_aes/ciphertext-data-empty.ct new file mode 100644 index 000000000..3eb401da7 Binary files /dev/null and b/performance_tests/test/resources/ciphertext/raw_aes/ciphertext-data-empty.ct differ diff --git a/performance_tests/test/resources/ciphertext/raw_aes/ciphertext-data-large.ct b/performance_tests/test/resources/ciphertext/raw_aes/ciphertext-data-large.ct new file mode 100644 index 000000000..ea9e7166d Binary files /dev/null and b/performance_tests/test/resources/ciphertext/raw_aes/ciphertext-data-large.ct differ diff --git a/performance_tests/test/resources/ciphertext/raw_aes/ciphertext-data-medium.ct b/performance_tests/test/resources/ciphertext/raw_aes/ciphertext-data-medium.ct new file mode 100644 index 000000000..e62387249 Binary files /dev/null and b/performance_tests/test/resources/ciphertext/raw_aes/ciphertext-data-medium.ct differ diff --git a/performance_tests/test/resources/ciphertext/raw_aes/ciphertext-data-small.ct b/performance_tests/test/resources/ciphertext/raw_aes/ciphertext-data-small.ct new file mode 100644 index 000000000..61c056b37 Binary files /dev/null and b/performance_tests/test/resources/ciphertext/raw_aes/ciphertext-data-small.ct differ diff --git a/performance_tests/test/resources/ciphertext/raw_rsa/ciphertext-data-empty.ct b/performance_tests/test/resources/ciphertext/raw_rsa/ciphertext-data-empty.ct new file mode 100644 index 000000000..202643e9a Binary files /dev/null and b/performance_tests/test/resources/ciphertext/raw_rsa/ciphertext-data-empty.ct differ diff --git a/performance_tests/test/resources/ciphertext/raw_rsa/ciphertext-data-large.ct b/performance_tests/test/resources/ciphertext/raw_rsa/ciphertext-data-large.ct new file mode 100644 index 000000000..259d83ea5 Binary files /dev/null and b/performance_tests/test/resources/ciphertext/raw_rsa/ciphertext-data-large.ct differ diff --git a/performance_tests/test/resources/ciphertext/raw_rsa/ciphertext-data-medium.ct b/performance_tests/test/resources/ciphertext/raw_rsa/ciphertext-data-medium.ct new file mode 100644 index 000000000..a249cfbaf Binary files /dev/null and b/performance_tests/test/resources/ciphertext/raw_rsa/ciphertext-data-medium.ct differ diff --git a/performance_tests/test/resources/ciphertext/raw_rsa/ciphertext-data-small.ct b/performance_tests/test/resources/ciphertext/raw_rsa/ciphertext-data-small.ct new file mode 100644 index 000000000..390a36a4b Binary files /dev/null and b/performance_tests/test/resources/ciphertext/raw_rsa/ciphertext-data-small.ct differ diff --git a/performance_tests/test/resources/plaintext/plaintext-data-empty.dat b/performance_tests/test/resources/plaintext/plaintext-data-empty.dat new file mode 100644 index 000000000..e69de29bb diff --git a/performance_tests/test/resources/plaintext/plaintext-data-large.dat b/performance_tests/test/resources/plaintext/plaintext-data-large.dat new file mode 100644 index 000000000..22bad9f3f --- /dev/null +++ b/performance_tests/test/resources/plaintext/plaintext-data-large.dat @@ -0,0 +1,21 @@ +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Et netus et malesuada fames. Bibendum enim facilisis gravida neque convallis. Tortor consequat id porta nibh venenatis cras. Lacus sed viverra tellus in hac habitasse platea dictumst. Ipsum dolor sit amet consectetur adipiscing elit pellentesque. Risus pretium quam vulputate dignissim suspendisse in. Ante in nibh mauris cursus mattis molestie a iaculis at. Nulla porttitor massa id neque aliquam vestibulum morbi blandit. Urna et pharetra pharetra massa massa ultricies mi quis. Leo duis ut diam quam nulla porttitor massa id. Vitae suscipit tellus mauris a diam maecenas sed enim ut. + +Non nisi est sit amet facilisis magna etiam tempor. Mi bibendum neque egestas congue quisque egestas diam in arcu. Volutpat est velit egestas dui id ornare arcu odio ut. Amet tellus cras adipiscing enim eu turpis egestas. Tortor dignissim convallis aenean et tortor at risus viverra. Interdum consectetur libero id faucibus nisl tincidunt eget. In eu mi bibendum neque egestas congue quisque egestas. Pellentesque habitant morbi tristique senectus et netus et malesuada fames. Leo vel orci porta non pulvinar. Amet massa vitae tortor condimentum. Malesuada fames ac turpis egestas maecenas pharetra. Feugiat nibh sed pulvinar proin gravida hendrerit lectus a. Quam elementum pulvinar etiam non quam lacus. Accumsan in nisl nisi scelerisque eu ultrices. Pretium aenean pharetra magna ac placerat vestibulum. Dui faucibus in ornare quam viverra orci sagittis eu volutpat. Amet venenatis urna cursus eget nunc scelerisque viverra mauris in. Penatibus et magnis dis parturient montes nascetur ridiculus mus mauris. Quis commodo odio aenean sed adipiscing diam donec adipiscing tristique. + +Leo a diam sollicitudin tempor id. Tempor orci eu lobortis elementum nibh. Sit amet commodo nulla facilisi nullam vehicula. Hendrerit gravida rutrum quisque non tellus. Diam vulputate ut pharetra sit. Semper feugiat nibh sed pulvinar proin gravida hendrerit lectus a. Tempus iaculis urna id volutpat lacus laoreet non curabitur gravida. Porttitor lacus luctus accumsan tortor posuere ac ut consequat semper. Tortor vitae purus faucibus ornare. Risus viverra adipiscing at in tellus integer. Suspendisse potenti nullam ac tortor vitae purus faucibus ornare suspendisse. Facilisis sed odio morbi quis commodo odio aenean sed. At auctor urna nunc id. Ac tortor vitae purus faucibus ornare suspendisse sed nisi. Suspendisse interdum consectetur libero id faucibus nisl. Tellus id interdum velit laoreet id. Mus mauris vitae ultricies leo integer. Metus vulputate eu scelerisque felis imperdiet proin. + +Venenatis cras sed felis eget velit aliquet sagittis id. Turpis cursus in hac habitasse. Magna fringilla urna porttitor rhoncus dolor purus non. In tellus integer feugiat scelerisque varius morbi. Tortor consequat id porta nibh venenatis cras sed. Ut sem viverra aliquet eget sit amet tellus cras. Semper risus in hendrerit gravida. Libero enim sed faucibus turpis in. Ultricies leo integer malesuada nunc vel risus commodo. Ipsum dolor sit amet consectetur adipiscing elit pellentesque habitant. Varius duis at consectetur lorem donec massa sapien faucibus et. Ornare arcu dui vivamus arcu felis bibendum ut tristique et. + +Diam quis enim lobortis scelerisque fermentum dui faucibus in. Cursus mattis molestie a iaculis at erat. Diam sit amet nisl suscipit adipiscing. Ultrices dui sapien eget mi proin sed libero. Purus ut faucibus pulvinar elementum integer enim neque. Ultricies mi quis hendrerit dolor magna eget. Morbi tincidunt ornare massa eget. Mauris cursus mattis molestie a iaculis at erat pellentesque. Phasellus vestibulum lorem sed risus. Sodales ut etiam sit amet nisl purus in. Habitant morbi tristique senectus et netus et. Consectetur lorem donec massa sapien faucibus et molestie. + +Montes nascetur ridiculus mus mauris vitae ultricies. Lectus urna duis convallis convallis. Pulvinar proin gravida hendrerit lectus. Semper auctor neque vitae tempus quam pellentesque nec. Donec pretium vulputate sapien nec. Id aliquet lectus proin nibh nisl. Enim ut sem viverra aliquet eget sit amet tellus. Vel orci porta non pulvinar neque laoreet suspendisse interdum consectetur. Feugiat vivamus at augue eget arcu dictum varius. Venenatis tellus in metus vulputate eu. Aliquam vestibulum morbi blandit cursus risus at ultrices mi tempus. Id venenatis a condimentum vitae. Lorem mollis aliquam ut porttitor leo a diam sollicitudin tempor. Rhoncus est pellentesque elit ullamcorper dignissim cras tincidunt lobortis. + +Nisi scelerisque eu ultrices vitae. Eu feugiat pretium nibh ipsum consequat nisl vel pretium. Commodo ullamcorper a lacus vestibulum sed arcu non odio. Sit amet cursus sit amet dictum. Fermentum iaculis eu non diam. Quis imperdiet massa tincidunt nunc pulvinar. Tempor commodo ullamcorper a lacus vestibulum sed. Venenatis urna cursus eget nunc scelerisque viverra mauris in. Vulputate mi sit amet mauris commodo quis imperdiet massa. Non nisi est sit amet facilisis magna etiam tempor orci. Consectetur libero id faucibus nisl tincidunt eget nullam. Sit amet risus nullam eget felis eget nunc. Aliquet porttitor lacus luctus accumsan. Vitae congue eu consequat ac felis donec. Vehicula ipsum a arcu cursus vitae congue mauris rhoncus. Fringilla phasellus faucibus scelerisque eleifend donec pretium vulputate. + +Massa eget egestas purus viverra. Nunc sed augue lacus viverra vitae congue eu consequat. Lectus quam id leo in. Augue eget arcu dictum varius duis. Nulla facilisi cras fermentum odio eu feugiat pretium. Adipiscing diam donec adipiscing tristique risus. Imperdiet dui accumsan sit amet. Volutpat commodo sed egestas egestas fringilla phasellus faucibus scelerisque. Dolor sit amet consectetur adipiscing elit duis. In fermentum et sollicitudin ac orci phasellus egestas tellus rutrum. Ridiculus mus mauris vitae ultricies leo integer malesuada. Nulla pharetra diam sit amet nisl. Nec dui nunc mattis enim ut tellus. Morbi non arcu risus quis varius quam quisque. Ac auctor augue mauris augue neque gravida in fermentum et. Morbi tincidunt augue interdum velit euismod. Sem viverra aliquet eget sit amet tellus cras adipiscing enim. Volutpat commodo sed egestas egestas fringilla phasellus faucibus scelerisque. Odio facilisis mauris sit amet. Amet mattis vulputate enim nulla aliquet. + +Nisi vitae suscipit tellus mauris a diam maecenas sed enim. Venenatis urna cursus eget nunc scelerisque viverra. Neque egestas congue quisque egestas diam in. Adipiscing vitae proin sagittis nisl. Sodales neque sodales ut etiam sit. Non consectetur a erat nam at. Ac felis donec et odio. Adipiscing tristique risus nec feugiat in fermentum posuere urna. Ultrices in iaculis nunc sed augue lacus viverra vitae. Enim sit amet venenatis urna. Amet consectetur adipiscing elit pellentesque. + +Venenatis a condimentum vitae sapien pellentesque. Ut faucibus pulvinar elementum integer enim neque. Nisl nunc mi ipsum faucibus vitae aliquet. Netus et malesuada fames ac. Et odio pellentesque diam volutpat commodo sed egestas egestas fringilla. Ut diam quam nulla porttitor massa id. Id donec ultrices tincidunt arcu non sodales neque sodales ut. Viverra ipsum nunc aliquet bibendum enim. Lacus vestibulum sed arcu non odio. Lobortis mattis aliquam faucibus purus in massa tempor. Tortor at auctor urna nunc id cursus metus aliquam eleifend. Ornare suspendisse sed nisi lacus sed viverra tellus in. Tristique magna sit amet purus gravida quis. At ultrices mi tempus imperdiet nulla malesuada. Erat imperdiet sed euismod nisi. Eleifend donec pretium vulputate sapien nec sagittis aliquam malesuada. Fermentum dui faucibus in ornare quam viverra orci sagittis. Nec dui nunc mattis enim ut tellus elementum sagittis. + +Suspendisse interdum consectetur libero id faucibus nisl. Bibendum enim facilisis gravida neque convallis. Nisi vitae suscipit tellus mauris a. Massa ultricies mi quis hendreri. \ No newline at end of file diff --git a/performance_tests/test/resources/plaintext/plaintext-data-medium.dat b/performance_tests/test/resources/plaintext/plaintext-data-medium.dat new file mode 100644 index 000000000..3313ba519 --- /dev/null +++ b/performance_tests/test/resources/plaintext/plaintext-data-medium.dat @@ -0,0 +1,11 @@ +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Et netus et malesuada fames. Bibendum enim facilisis gravida neque convallis. Tortor consequat id porta nibh venenatis cras. Lacus sed viverra tellus in hac habitasse platea dictumst. Ipsum dolor sit amet consectetur adipiscing elit pellentesque. Risus pretium quam vulputate dignissim suspendisse in. Ante in nibh mauris cursus mattis molestie a iaculis at. Nulla porttitor massa id neque aliquam vestibulum morbi blandit. Urna et pharetra pharetra massa massa ultricies mi quis. Leo duis ut diam quam nulla porttitor massa id. Vitae suscipit tellus mauris a diam maecenas sed enim ut. + +Non nisi est sit amet facilisis magna etiam tempor. Mi bibendum neque egestas congue quisque egestas diam in arcu. Volutpat est velit egestas dui id ornare arcu odio ut. Amet tellus cras adipiscing enim eu turpis egestas. Tortor dignissim convallis aenean et tortor at risus viverra. Interdum consectetur libero id faucibus nisl tincidunt eget. In eu mi bibendum neque egestas congue quisque egestas. Pellentesque habitant morbi tristique senectus et netus et malesuada fames. Leo vel orci porta non pulvinar. Amet massa vitae tortor condimentum. Malesuada fames ac turpis egestas maecenas pharetra. Feugiat nibh sed pulvinar proin gravida hendrerit lectus a. Quam elementum pulvinar etiam non quam lacus. Accumsan in nisl nisi scelerisque eu ultrices. Pretium aenean pharetra magna ac placerat vestibulum. Dui faucibus in ornare quam viverra orci sagittis eu volutpat. Amet venenatis urna cursus eget nunc scelerisque viverra mauris in. Penatibus et magnis dis parturient montes nascetur ridiculus mus mauris. Quis commodo odio aenean sed adipiscing diam donec adipiscing tristique. + +Leo a diam sollicitudin tempor id. Tempor orci eu lobortis elementum nibh. Sit amet commodo nulla facilisi nullam vehicula. Hendrerit gravida rutrum quisque non tellus. Diam vulputate ut pharetra sit. Semper feugiat nibh sed pulvinar proin gravida hendrerit lectus a. Tempus iaculis urna id volutpat lacus laoreet non curabitur gravida. Porttitor lacus luctus accumsan tortor posuere ac ut consequat semper. Tortor vitae purus faucibus ornare. Risus viverra adipiscing at in tellus integer. Suspendisse potenti nullam ac tortor vitae purus faucibus ornare suspendisse. Facilisis sed odio morbi quis commodo odio aenean sed. At auctor urna nunc id. Ac tortor vitae purus faucibus ornare suspendisse sed nisi. Suspendisse interdum consectetur libero id faucibus nisl. Tellus id interdum velit laoreet id. Mus mauris vitae ultricies leo integer. Metus vulputate eu scelerisque felis imperdiet proin. + +Venenatis cras sed felis eget velit aliquet sagittis id. Turpis cursus in hac habitasse. Magna fringilla urna porttitor rhoncus dolor purus non. In tellus integer feugiat scelerisque varius morbi. Tortor consequat id porta nibh venenatis cras sed. Ut sem viverra aliquet eget sit amet tellus cras. Semper risus in hendrerit gravida. Libero enim sed faucibus turpis in. Ultricies leo integer malesuada nunc vel risus commodo. Ipsum dolor sit amet consectetur adipiscing elit pellentesque habitant. Varius duis at consectetur lorem donec massa sapien faucibus et. Ornare arcu dui vivamus arcu felis bibendum ut tristique et. + +Diam quis enim lobortis scelerisque fermentum dui faucibus in. Cursus mattis molestie a iaculis at erat. Diam sit amet nisl suscipit adipiscing. Ultrices dui sapien eget mi proin sed libero. Purus ut faucibus pulvinar elementum integer enim neque. Ultricies mi quis hendrerit dolor magna eget. Morbi tincidunt ornare massa eget. Mauris cursus mattis molestie a iaculis at erat pellentesque. Phasellus vestibulum lorem sed risus. Sodales ut etiam sit amet nisl purus in. Habitant morbi tristique senectus et netus et. Consectetur lorem donec massa sapien faucibus et molestie. + +Montes nascetur ridiculus mus mauris vitae ultricies. Lectus urna duis convallis convallis. Pulvinar pr. \ No newline at end of file diff --git a/performance_tests/test/resources/plaintext/plaintext-data-small.dat b/performance_tests/test/resources/plaintext/plaintext-data-small.dat new file mode 100644 index 000000000..b8475e61f --- /dev/null +++ b/performance_tests/test/resources/plaintext/plaintext-data-small.dat @@ -0,0 +1 @@ +Lorem ipsum dolor sit amet, consect. \ No newline at end of file diff --git a/performance_tests/tox.ini b/performance_tests/tox.ini new file mode 100644 index 000000000..1b7d073aa --- /dev/null +++ b/performance_tests/tox.ini @@ -0,0 +1,215 @@ +[tox] +envlist = + # The performance tests only work for python 3.11 and 3.12 + py{311,312}-performance_tests-mpl + bandit, doc8 + ; {flake8, pylint}{,-tests}, + isort-check, black-check, + # prone to false positives + vulture + +# Additional test environments: +# +# linters :: Runs all linters over all source code. +# linters-tests :: Runs all linters over all tests. + +# Autoformatter helper environments: +# +# autoformat : Apply all autoformatters +# +# black-check : Check for "black" issues +# blacken : Fix all "black" issues +# +# isort-seed : Generate a known_third_party list for isort. +# NOTE: make the "known_third_party = " line in setup.cfg before running this +# NOTE: currently it incorrectly identifies this library too; make sure you remove it +# isort-check : Check for isort issues +# isort : Fix isort issues + +# Operational helper environments: +# +# build :: Builds source and wheel dist files. +# test-release :: Builds dist files and uploads to testpypi pypirc profile. +# release :: Builds dist files and uploads to pypi pypirc profile. + +[testenv:base-command] +commands = pytest test/ +deps = + click + + +[testenv] +passenv = + # Pass through AWS credentials + AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN \ + # AWS Role access in CodeBuild is via the contaner URI + AWS_CONTAINER_CREDENTIALS_RELATIVE_URI \ + # Pass through AWS profile name (useful for local testing) + AWS_PROFILE +sitepackages = False +deps = + -rrequirements.txt + # Install the MPL requirements if the `-mpl` suffix is present + mpl: -rrequirements_mpl.txt + .. +commands = + performance_tests: {[testenv:base-command]commands} + +[testenv:blacken-src] +basepython = python3 +deps = -r../dev_requirements/linter-requirements.txt +commands = + black --line-length 120 \ + src/aws_encryption_sdk_performance_tests/ \ + setup.py \ + test/ \ + {posargs} + +# Linters +[testenv:flake8] +basepython = python3 +deps = -r../dev_requirements/linter-requirements.txt +commands = + flake8 \ + src/aws_encryption_sdk_performance_tests/ \ + setup.py \ + {posargs} + +[testenv:flake8-tests] +basepython = {[testenv:flake8]basepython} +deps = -r../dev_requirements/linter-requirements.txt +commands = + flake8 \ + # Ignore F811 redefinition errors in tests (breaks with pytest-mock use) + # E203 is not PEP8 compliant https://github.com/ambv/black#slices + # W503 is not PEP8 compliant https://github.com/ambv/black#line-breaks--binary-operators + --ignore F811,E203,W503,D \ + test/ + +[testenv:pylint] +basepython = python3 +deps = + -r../dev_requirements/linter-requirements.txt +commands = + pylint \ + --rcfile=pylintrc \ + src/aws_encryption_sdk_performance_tests/ \ + setup.py \ + {posargs} + +[testenv:pylint-tests] +basepython = {[testenv:pylint]basepython} +deps = {[testenv:pylint]deps} +commands = + pylint \ + --rcfile=pylintrc \ + test/ \ + {posargs} + +[testenv:blacken] +basepython = python3 +deps = + {[testenv:blacken-src]deps} +commands = + {[testenv:blacken-src]commands} + +[testenv:black-check] +basepython = python3 +deps = + {[testenv:blacken]deps} +commands = + {[testenv:blacken-src]commands} --diff + +[testenv:isort-seed] +basepython = python3 +deps = -r../dev_requirements/linter-requirements.txt +commands = seed-isort-config + +[testenv:isort] +basepython = python3 +deps = -r../dev_requirements/linter-requirements.txt +commands = isort -rc \ + src \ + test \ + setup.py \ + {posargs} + +[testenv:isort-check] +basepython = python3 +deps = {[testenv:isort]deps} +commands = {[testenv:isort]commands} -c + +[testenv:autoformat] +basepython = python3 +deps = + {[testenv:blacken]deps} + {[testenv:isort]deps} + .. +commands = + {[testenv:blacken]commands} + {[testenv:isort]commands} + +[testenv:doc8] +basepython = python3 +deps = -r../dev_requirements/linter-requirements.txt +commands = doc8 README.rst + +[testenv:readme] +basepython = python3 +deps = -r../dev_requirements/linter-requirements.txt +commands = python setup.py check -r -s + +[testenv:bandit] +basepython = python3 +deps = -r../dev_requirements/linter-requirements.txt +commands = bandit -r src/aws_encryption_sdk_performance_tests/ + +[testenv:linters] +basepython = python3 +deps = + {[testenv:flake8]deps} + {[testenv:pylint]deps} + {[testenv:doc8]deps} + {[testenv:readme]deps} + {[testenv:bandit]deps} +commands = + {[testenv:flake8]commands} + {[testenv:pylint]commands} + {[testenv:doc8]commands} + {[testenv:readme]commands} + {[testenv:bandit]commands} + +# Release tooling +[testenv:park] +basepython = python3 +skip_install = true +deps = -r../dev_requirements/release-requirements.txt +commands = python setup.py park + +[testenv:build] +basepython = python3 +skip_install = true +deps = + -r../dev_requirements/release-requirements.txt +commands = + python setup.py sdist bdist_wheel + +[testenv:test-release] +basepython = python3 +skip_install = true +deps = + {[testenv:build]deps} + twine +commands = + {[testenv:build]commands} + twine upload --skip-existing --repository testpypi dist/* + +[testenv:release] +basepython = python3 +skip_install = true +deps = + {[testenv:build]deps} + twine +commands = + {[testenv:build]commands} + twine upload --skip-existing --repository pypi dist/* diff --git a/tox.ini b/tox.ini index 8d4af1d2d..9152f51a6 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,7 @@ [tox] envlist = # <3.11: run all non-MPL tests - py{37,38,39,310}-{local,integ,accept,examples}, + py{38,39,310}-{local,integ,accept,examples}, # >=3.11: run all tests with MPL installed and without MPL installed # The `-mpl` suffix tells tox to install the MPL. # In the case where the suffix IS NOT appended,