diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
new file mode 100644
index 0000000..b08c76c
--- /dev/null
+++ b/.github/CONTRIBUTING.md
@@ -0,0 +1,23 @@
+# Contributing
+
+First of all, **thank you** for contributing.
+
+Bugs or feature requests can be posted online on the GitHub issues section of the project.
+
+Few rules to ease code reviews and merges:
+
+- You MUST follow the [PSR-12](http://www.php-fig.org/psr/psr-12/) coding standard.
+- You MUST run the test suite.
+- You MUST write (or update) unit tests when bugs are fixed or features are added.
+- You SHOULD write documentation.
+
+To contribute use [Pull Requests](https://help.github.com/articles/using-pull-requests), please, write commit messages that make sense, and rebase your branch before submitting your PR.
+
+May be asked to squash your commits too. This is used to "clean" your Pull Request before merging it, avoiding commits such as fix tests, fix 2, fix 3, etc.
+
+Run test suite
+------------
+
+* install composer: `curl -s http://getcomposer.org/installer | php`
+* install dependencies: `php composer.phar install`
+* run tests: `vendor/bin/phpunit`
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..726574c
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,2 @@
+github: Spomky
+patreon: FlorentMorselli
diff --git a/.github/ISSUE_TEMPLATE/1_Bug_report.md b/.github/ISSUE_TEMPLATE/1_Bug_report.md
new file mode 100644
index 0000000..3a3e9fd
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/1_Bug_report.md
@@ -0,0 +1,21 @@
+---
+name: 🐛 Bug Report
+about: ⚠️ See below for security reports
+labels: Bug
+
+---
+
+**Version(s) affected**: x.y.z
+
+**Description**
+
+
+**How to reproduce**
+
+
+**Possible Solution**
+
+
+**Additional context**
+
diff --git a/.github/ISSUE_TEMPLATE/2_Feature_request.md b/.github/ISSUE_TEMPLATE/2_Feature_request.md
new file mode 100644
index 0000000..8ffd974
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/2_Feature_request.md
@@ -0,0 +1,12 @@
+---
+name: 🚀 Feature Request
+about: Ideas for new features and improvements
+
+---
+
+**Description**
+
+
+**Example**
+
diff --git a/.github/ISSUE_TEMPLATE/3_Support_question.md b/.github/ISSUE_TEMPLATE/3_Support_question.md
new file mode 100644
index 0000000..6b4f060
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/3_Support_question.md
@@ -0,0 +1,11 @@
+---
+name: ⛔ Support Question
+about: We usually do not provide support. Please ask your question on https://stackoverflow.com/
+
+---
+
+We use GitHub issues only to discuss bugs and new features.
+For this kind of questions about using the library or the bundle, please use
+https://stackoverflow.com/ using the tags `[aes]` and `[php]`
+
+Thanks!
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/4_Documentation_issue.md b/.github/ISSUE_TEMPLATE/4_Documentation_issue.md
new file mode 100644
index 0000000..26cd199
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/4_Documentation_issue.md
@@ -0,0 +1,5 @@
+---
+name: 📖 Documentation Issue
+about: To report typo or obsolete section in the documentation
+
+---
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000..1beb0a3
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,19 @@
+| Q | A
+| ------------- | ---
+| Branch? |
+| Bug fix? | yes/no
+| New feature? | yes/no
+| Deprecations? | yes/no
+| Tickets | Fix #...
+| License | MIT
+
\ No newline at end of file
diff --git a/.github/stale.yml b/.github/stale.yml
new file mode 100644
index 0000000..3c84124
--- /dev/null
+++ b/.github/stale.yml
@@ -0,0 +1,8 @@
+daysUntilStale: 60
+daysUntilClose: 7
+staleLabel: wontfix
+markComment: >
+ This issue has been automatically marked as stale because it has not had
+ recent activity. It will be closed if no further activity occurs. Thank you
+ for your contributions.
+closeComment: false
diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml
new file mode 100644
index 0000000..68fe9d1
--- /dev/null
+++ b/.github/workflows/coding-standards.yml
@@ -0,0 +1,32 @@
+name: Coding Standards
+
+on: [push]
+
+jobs:
+ tests:
+ runs-on: ${{ matrix.operating-system }}
+ strategy:
+ matrix:
+ operating-system: [ubuntu-latest]
+ php-versions: ['8.0']
+ name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }}
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ with:
+ ref: ${{ github.head_ref }}
+
+ - name: Setup PHP, with composer and extensions
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php-versions }}
+ extensions: json, mbstring, openssl, sqlite3
+ coverage: xdebug
+
+ - name: Install Composer dependencies
+ run: |
+ composer update --no-progress --no-suggest --prefer-dist --optimize-autoloader
+
+ - name: CONDING STANDARDS
+ run: make ci-cs
diff --git a/.github/workflows/mutation-tests.yml b/.github/workflows/mutation-tests.yml
new file mode 100644
index 0000000..132555a
--- /dev/null
+++ b/.github/workflows/mutation-tests.yml
@@ -0,0 +1,35 @@
+name: Mutation Testing
+
+on: [push]
+
+jobs:
+ tests:
+ runs-on: ${{ matrix.operating-system }}
+ strategy:
+ matrix:
+ operating-system: [ubuntu-latest]
+ php-versions: ['8.0']
+ name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }}
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ with:
+ ref: ${{ github.head_ref }}
+
+ - name: Setup PHP, with composer and extensions
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php-versions }}
+ extensions: json, mbstring, openssl, sqlite3
+ coverage: xdebug
+
+ - name: Install Composer dependencies
+ run: |
+ composer update --no-progress --no-suggest --prefer-dist --optimize-autoloader
+
+ - name: Fetch Git base reference
+ run: git fetch --depth=1 origin $GITHUB_BASE_REF
+
+ - name: Infection
+ run: make ci-mu
diff --git a/.github/workflows/rector_checkstyle.yaml b/.github/workflows/rector_checkstyle.yaml
new file mode 100644
index 0000000..e0d3f9c
--- /dev/null
+++ b/.github/workflows/rector_checkstyle.yaml
@@ -0,0 +1,29 @@
+name: Rector Checkstyle
+
+on: [push]
+
+jobs:
+ tests:
+ runs-on: ${{ matrix.operating-system }}
+ strategy:
+ matrix:
+ operating-system: [ ubuntu-latest ]
+ php-versions: [ '8.0' ]
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ with:
+ ref: ${{ github.head_ref }}
+
+ - name: Setup PHP, with composer and extensions
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php-versions }}
+ extensions: json, mbstring, openssl, sqlite3
+ coverage: none
+
+ - name: Install Composer dependencies
+ run: composer update --no-progress --no-suggest --prefer-dist --optimize-autoloader
+
+ - name: Rector
+ run: make rector
diff --git a/.github/workflows/static-analyze.yml b/.github/workflows/static-analyze.yml
new file mode 100644
index 0000000..45dedcf
--- /dev/null
+++ b/.github/workflows/static-analyze.yml
@@ -0,0 +1,32 @@
+name: Static Analyze
+
+on: [push]
+
+jobs:
+ tests:
+ runs-on: ${{ matrix.operating-system }}
+ strategy:
+ matrix:
+ operating-system: [ubuntu-latest]
+ php-versions: ['8.0']
+ name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }}
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ with:
+ ref: ${{ github.head_ref }}
+
+ - name: Setup PHP, with composer and extensions
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php-versions }}
+ extensions: json, mbstring, openssl, sqlite3
+ coverage: xdebug
+
+ - name: Install Composer dependencies
+ run: |
+ composer update --no-progress --no-suggest --prefer-dist --optimize-autoloader
+
+ - name: PHPStan
+ run: make st
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
new file mode 100644
index 0000000..740fc75
--- /dev/null
+++ b/.github/workflows/tests.yml
@@ -0,0 +1,32 @@
+name: Unit and Functional Tests
+
+on: [push]
+
+jobs:
+ tests:
+ runs-on: ${{ matrix.operating-system }}
+ strategy:
+ matrix:
+ operating-system: [ ubuntu-latest ]
+ php-versions: [ '8.0', '8.1' ]
+ name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }}
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ with:
+ ref: ${{ github.head_ref }}
+
+ - name: Setup PHP, with composer and extensions
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php-versions }}
+ extensions: json, mbstring, openssl, sqlite3
+ coverage: xdebug
+
+ - name: Install Composer dependencies
+ run: |
+ composer update --no-progress --no-suggest --prefer-dist --optimize-autoloader
+
+ - name: Run tests
+ run: make ci-cc
diff --git a/.scrutinizer.yml b/.scrutinizer.yml
deleted file mode 100644
index c95e823..0000000
--- a/.scrutinizer.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-before_commands:
- - "composer install --no-interaction"
-
-tools:
- php_sim: false
- php_changetracking: true
- php_cpd: true
- php_mess_detector: true
- php_code_sniffer: true
- php_analyzer: true
- sensiolabs_security_checker: true
- php_code_coverage: false
- php_pdepend:
- excluded_dirs: [vendor, doc]
-filter:
- excluded_paths: [vendor/*, doc/*]
-build_failure_conditions:
- - 'elements.rating(<= C).exists' # No classes/methods with a rating of C or worse
- - 'elements.rating(<= C).new.exists' # No new classes/methods with a rating of C or worse
- - 'patches.label("Doc Comments").exists' # No doc comments patches allowed
- - 'patches.label("Spacing").new.count > 1' # More than 1 new spacing patch
- - 'issues.label("coding-style").exists' # No coding style issues allowed
- - 'issues.label("coding-style").new.exists' # No new coding style issues allowed
- - 'issues.severity(>= MAJOR).new.exists' # New issues of major or higher severity
- - 'project.metric("scrutinizer.quality", < 9)' # Code Quality Rating drops below 9
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index f43c80b..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-language: php
-
-matrix:
- allow_failures:
- - php: nightly
- fast_finish: true
- include:
- - php: 7.2
- - php: 7.3
- - php: 7.4
- - php: nightly
-
-before_script:
- - composer self-update
- - composer install
- - mkdir -p build/logs
-
-script:
- - vendor/bin/phpunit --coverage-clover build/logs/clover.xml
-
-after_success:
- - vendor/bin/coveralls --no-interaction
- - php -r "require_once 'vendor/autoload.php'; AESKW\Tests\Performance::run();";
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..1ca240e
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,50 @@
+mu: vendor ## Mutation tests
+ vendor/bin/infection -s --threads=$(nproc) --min-msi=75 --min-covered-msi=75
+
+tests: vendor ## Run all tests
+ vendor/bin/phpunit --color
+
+cc: vendor ## Show test coverage rates (HTML)
+ vendor/bin/phpunit --coverage-html ./build
+
+cs: vendor ## Fix all files using defined ECS rules
+ vendor/bin/ecs check --fix
+
+tu: vendor ## Run only unit tests
+ vendor/bin/phpunit --color --group Unit
+
+ti: vendor ## Run only integration tests
+ vendor/bin/phpunit --color --group Integration
+
+tf: vendor ## Run only functional tests
+ vendor/bin/phpunit --color --group Functional
+
+st: vendor ## Run static analyse
+ vendor/bin/phpstan analyse
+
+
+################################################
+
+ci-mu: vendor ## Mutation tests (for Github only)
+ vendor/bin/infection --logger-github -s --threads=$(nproc) --min-msi=75 --min-covered-msi=75
+
+ci-cc: vendor ## Show test coverage rates (console)
+ vendor/bin/phpunit --coverage-text
+
+ci-cs: vendor ## Check all files using defined ECS rules
+ vendor/bin/ecs check
+
+################################################
+
+
+vendor: composer.json composer.lock
+ composer validate
+ composer install
+
+rector: vendor ## Check all files using Rector
+ vendor/bin/rector process --ansi --dry-run --xdebug
+
+.DEFAULT_GOAL := help
+help:
+ @grep -E '(^[a-zA-Z_-]+:.*?##.*$$)|(^##)' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[32m%-30s\033[0m %s\n", $$1, $$2}' | sed -e 's/\[32m##/[33m/'
+.PHONY: help
diff --git a/README.md b/README.md
index 564d223..60d2eaa 100644
--- a/README.md
+++ b/README.md
@@ -1,18 +1,18 @@
PHP AES Key Wrap
================
-[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/Spomky-Labs/aes-key-wrap/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/Spomky-Labs/aes-key-wrap/?branch=master)
-[![Coverage Status](https://coveralls.io/repos/Spomky-Labs/aes-key-wrap/badge.svg?branch=master&service=github)](https://coveralls.io/github/Spomky-Labs/aes-key-wrap?branch=master)
+![Build Status](https://github.com/Spomky-Labs/aes-key-wrap/workflows/Coding%20Standards/badge.svg)
+![Build Status](https://github.com/Spomky-Labs/aes-key-wrap/workflows/Static%20Analyze/badge.svg)
+![Build Status](https://github.com/Spomky-Labs/aes-key-wrap/workflows/Rector%20Checkstyle/badge.svg)
-[![Build Status](https://travis-ci.org/Spomky-Labs/aes-key-wrap.svg?branch=master)](https://travis-ci.org/Spomky-Labs/aes-key-wrap)
+![Build Status](https://github.com/Spomky-Labs/aes-key-wrap/workflows/Unit%20and%20Functional%20Tests/badge.svg)
-[![SensioLabsInsight](https://insight.sensiolabs.com/projects/e61c91cf-1860-4416-946b-4c7b74ea01a5/big.png)](https://insight.sensiolabs.com/projects/e61c91cf-1860-4416-946b-4c7b74ea01a5)
-
-[![Latest Stable Version](https://poser.pugx.org/spomky-labs/aes-key-wrap/v/stable.png)](https://packagist.org/packages/spomky-labs/aes-key-wrap)
-[![Latest Unstable Version](https://poser.pugx.org/spomky-labs/aes-key-wrap/v/unstable.png)](https://packagist.org/packages/spomky-labs/aes-key-wrap)
-[![Total Downloads](https://poser.pugx.org/spomky-labs/aes-key-wrap/downloads.png)](https://packagist.org/packages/spomky-labs/aes-key-wrap)
-[![License](https://poser.pugx.org/spomky-labs/aes-key-wrap/license.png)](https://packagist.org/packages/spomky-labs/aes-key-wrap)
+![Build Status](https://github.com/Spomky-Labs/aes-key-wrap/workflows/Mutation%20Testing/badge.svg)
+[![Latest Stable Version](https://poser.pugx.org/Spomky-Labs/aes-key-wrap/v/stable.png)](https://packagist.org/packages/Spomky-Labs/aes-key-wrap)
+[![Total Downloads](https://poser.pugx.org/Spomky-Labs/aes-key-wrap/downloads.png)](https://packagist.org/packages/Spomky-Labs/aes-key-wrap)
+[![Latest Unstable Version](https://poser.pugx.org/Spomky-Labs/aes-key-wrap/v/unstable.png)](https://packagist.org/packages/Spomky-Labs/aes-key-wrap)
+[![License](https://poser.pugx.org/Spomky-Labs/aes-key-wrap/license.png)](https://packagist.org/packages/Spomky-Labs/aes-key-wrap)
This library provides an implementation of the [RFC 3394 (Advanced Encryption Standard (AES) Key Wrap Algorithm)](https://tools.ietf.org/html/rfc3394) and the [RFC 5649 (Advanced Encryption Standard (AES) Key Wrap with Padding Algorithm)](https://tools.ietf.org/html/rfc5649).
@@ -22,10 +22,8 @@ The release process [is described here](doc/Release.md).
# Prerequisites
-This library needs at least `PHP 7.1`.
-It has been successfully tested using `PHP 7.1`, `PHP 7.2` and `HHVM`.
-
-For `PHP 5.4+`, please use the version `3.x` of this library.
+This library needs at least `PHP 8.0`.
+It has been successfully tested using `8.0` and `8.1`.
# Installation
@@ -45,12 +43,20 @@ I bring solutions to your problems and answer your questions.
If you really love that project and the work I have done or if you want I prioritize your issues, then you can help me out for a couple of :beers: or more!
+[Become a sponsor](https://github.com/sponsors/Spomky)
+
+Or
+
[![Become a Patreon](https://c5.patreon.com/external/logo/become_a_patron_button.png)](https://www.patreon.com/FlorentMorselli)
# Contributing
Requests for new features, bug fixed and all other ideas to make this library useful are welcome. [Please follow these best practices](doc/Contributing.md).
+If you discover a security vulnerability within the project, please **don't use the bug tracker and don't publish it publicly**.
+Instead, all security issues must be sent to security [at] spomky-labs.com.
+
+
# Licence
This software is release under [MIT licence](LICENSE).
diff --git a/composer.json b/composer.json
index 7b1b616..025ada5 100644
--- a/composer.json
+++ b/composer.json
@@ -22,24 +22,20 @@
}
},
"require": {
- "php": ">=7.2",
+ "php": ">=8.0",
"ext-mbstring": "*",
- "lib-openssl": "*",
- "thecodingmachine/safe": "^1.1"
+ "ext-openssl": "*"
},
"require-dev": {
- "phpunit/phpunit": "^7.0|^8.0|^9.0",
- "php-coveralls/php-coveralls": "^2.0",
- "phpstan/phpstan": "^0.12",
- "phpstan/phpstan-beberlei-assert": "^0.12",
- "phpstan/phpstan-deprecation-rules": "^0.12",
- "phpstan/phpstan-phpunit": "^0.12",
- "phpstan/phpstan-strict-rules": "^0.12",
- "thecodingmachine/phpstan-safe-rule": "^1.0"
- },
- "extra": {
- "branch-alias": {
- "dev-master": "5.0.x-dev"
- }
+ "phpunit/phpunit": "^9.0",
+ "phpstan/phpstan": "^1.0",
+ "phpstan/phpstan-beberlei-assert": "^1.0",
+ "phpstan/phpstan-deprecation-rules": "^1.0",
+ "phpstan/phpstan-phpunit": "^1.0",
+ "phpstan/phpstan-strict-rules": "^1.0",
+ "phpstan/extension-installer": "^1.1",
+ "symplify/easy-coding-standard": "^10.0",
+ "rector/rector": "^0.12.5",
+ "infection/infection": "^0.25.4"
}
}
diff --git a/doc/Contributing.md b/doc/Contributing.md
index 67ca7ac..82becb8 100644
--- a/doc/Contributing.md
+++ b/doc/Contributing.md
@@ -1,5 +1,5 @@
Contributing
-=============================
+============
First of all, **thank you** for contributing.
diff --git a/doc/Release.md b/doc/Release.md
index e52a90c..dbce213 100644
--- a/doc/Release.md
+++ b/doc/Release.md
@@ -9,8 +9,6 @@ We manage its releases through features and time-based models.
The meaning of "patch" "minor" and "major" comes from the Semantic [Versioning strategy](http://semver.org/).
-This release process applies from version 1.0.x.
-
### Backwards Compatibility
We allow developers to upgrade with confidence from one minor version to the next one.
diff --git a/ecs.php b/ecs.php
new file mode 100644
index 0000000..d489c29
--- /dev/null
+++ b/ecs.php
@@ -0,0 +1,124 @@
+import(SetList::PSR_12);
+ $containerConfigurator->import(SetList::PHP_CS_FIXER);
+ $containerConfigurator->import(SetList::PHP_CS_FIXER_RISKY);
+ $containerConfigurator->import(SetList::CLEAN_CODE);
+ $containerConfigurator->import(SetList::SYMFONY);
+ $containerConfigurator->import(SetList::DOCTRINE_ANNOTATIONS);
+ $containerConfigurator->import(SetList::SPACES);
+ $containerConfigurator->import(SetList::PHPUNIT);
+ $containerConfigurator->import(SetList::SYMPLIFY);
+ $containerConfigurator->import(SetList::ARRAY);
+ $containerConfigurator->import(SetList::COMMON);
+ $containerConfigurator->import(SetList::COMMENTS);
+ $containerConfigurator->import(SetList::CONTROL_STRUCTURES);
+ $containerConfigurator->import(SetList::DOCBLOCK);
+ $containerConfigurator->import(SetList::NAMESPACES);
+ $containerConfigurator->import(SetList::STRICT);
+
+ $services = $containerConfigurator->services();
+ $services->set(StrictParamFixer::class);
+ $services->set(StrictComparisonFixer::class);
+ $services->set(ArraySyntaxFixer::class)
+ ->call('configure', [[
+ 'syntax' => 'short',
+ ]])
+ ;
+ $services->set(ArrayIndentationFixer::class);
+ $services->set(OrderedImportsFixer::class);
+ $services->set(ProtectedToPrivateFixer::class);
+ $services->set(DeclareStrictTypesFixer::class);
+ $services->set(NativeConstantInvocationFixer::class);
+ $services->set(NativeFunctionInvocationFixer::class)
+ ->call('configure', [[
+ 'include' => ['@compiler_optimized'],
+ 'scope' => 'namespaced',
+ 'strict' => true,
+ ]])
+ ;
+ $services->set(MbStrFunctionsFixer::class);
+ $services->set(LinebreakAfterOpeningTagFixer::class);
+ $services->set(CombineConsecutiveIssetsFixer::class);
+ $services->set(CombineConsecutiveUnsetsFixer::class);
+ $services->set(CompactNullableTypehintFixer::class);
+ $services->set(NoSuperfluousElseifFixer::class);
+ $services->set(NoSuperfluousPhpdocTagsFixer::class);
+ $services->set(PhpdocTrimConsecutiveBlankLineSeparationFixer::class);
+ $services->set(PhpdocOrderFixer::class);
+ $services->set(SimplifiedNullReturnFixer::class);
+ $services->set(HeaderCommentFixer::class)
+ ->call('configure', [[
+ 'header' => $header,
+ ]])
+ ;
+ $services->set(AlignMultilineCommentFixer::class)
+ ->call('configure', [[
+ 'comment_type' => 'all_multiline',
+ ]])
+ ;
+ $services->set(PhpUnitTestAnnotationFixer::class)
+ ->call('configure', [[
+ 'style' => 'annotation',
+ ]])
+ ;
+ $services->set(PhpUnitTestCaseStaticMethodCallsFixer::class);
+ $services->set(GlobalNamespaceImportFixer::class)
+ ->call('configure', [[
+ 'import_classes' => true,
+ 'import_constants' => true,
+ 'import_functions' => true,
+ ]])
+ ;
+
+ $services->remove(PhpUnitTestClassRequiresCoversFixer::class);
+
+ $parameters = $containerConfigurator->parameters();
+ $parameters
+ ->set(Option::PARALLEL, true)
+ ->set(Option::PATHS, [__DIR__])
+ ->set(Option::SKIP, [
+ __DIR__ . '/src/Kernel.php',
+ __DIR__ . '/assets',
+ __DIR__ . '/bin',
+ __DIR__ . '/config',
+ __DIR__ . '/heroku',
+ __DIR__ . '/public',
+ __DIR__ . '/var',
+ ])
+ ;
+};
diff --git a/infection.json b/infection.json
new file mode 100644
index 0000000..17bf976
--- /dev/null
+++ b/infection.json
@@ -0,0 +1,15 @@
+{
+ "source": {
+ "directories": [
+ "src"
+ ]
+ },
+ "timeout": 3,
+ "logs": {
+ "text": "infection.txt"
+ },
+ "mutators": {
+ "@default": true,
+ "@function_signature": true
+ }
+}
diff --git a/infection.txt b/infection.txt
new file mode 100644
index 0000000..4a97421
--- /dev/null
+++ b/infection.txt
@@ -0,0 +1,721 @@
+Escaped mutants:
+================
+
+1) /home/florent/PhpstormProjects/aes-key-wrap/src/A128KW.php:11 [M] ProtectedVisibility
+
+--- Original
++++ New
+@@ @@
+ final class A128KW implements Wrapper
+ {
+ use AESKW;
+- protected static function getMethod() : string
++ private static function getMethod() : string
+ {
+ return 'aes-128-ecb';
+ }
+ }
+
+
+2) /home/florent/PhpstormProjects/aes-key-wrap/src/A192KW.php:11 [M] ProtectedVisibility
+
+--- Original
++++ New
+@@ @@
+ final class A192KW implements Wrapper
+ {
+ use AESKW;
+- protected static function getMethod() : string
++ private static function getMethod() : string
+ {
+ return 'aes-192-ecb';
+ }
+ }
+
+
+3) /home/florent/PhpstormProjects/aes-key-wrap/src/A256KW.php:11 [M] ProtectedVisibility
+
+--- Original
++++ New
+@@ @@
+ final class A256KW implements Wrapper
+ {
+ use AESKW;
+- protected static function getMethod() : string
++ private static function getMethod() : string
+ {
+ return 'aes-256-ecb';
+ }
+ }
+
+
+4) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:31 [M] MBString
+
+--- Original
++++ New
+@@ @@
+ {
+ $A = self::getInitialValue($key, $padding_enabled);
+ self::checkKeySize($key, $padding_enabled);
+- $P = mb_str_split($key, 8, '8bit');
++ $P = str_split($key, 8);
+ $N = count($P);
+ $C = [];
+ if ($N === 1) {
+
+
+5) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:38 [M] IncrementInteger
+
+--- Original
++++ New
+@@ @@
+ if ($N === 1) {
+ $B = self::encrypt($kek, $A . $P[0]);
+ $C[0] = self::getMSB($B);
+- $C[1] = self::getLSB($B);
++ $C[2] = self::getLSB($B);
+ } elseif ($N > 1) {
+ $R = $P;
+ for ($j = 0; $j <= 5; ++$j) {
+
+
+6) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:39 [M] GreaterThan
+
+--- Original
++++ New
+@@ @@
+ $B = self::encrypt($kek, $A . $P[0]);
+ $C[0] = self::getMSB($B);
+ $C[1] = self::getLSB($B);
+- } elseif ($N > 1) {
++ } elseif ($N >= 1) {
+ $R = $P;
+ for ($j = 0; $j <= 5; ++$j) {
+ for ($i = 1; $i <= $N; ++$i) {
+
+
+7) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:62 [M] FalseValue
+
+--- Original
++++ New
+@@ @@
+ *
+ * @return string The key unwrapped
+ */
+- public static function unwrap(string $kek, string $key, bool $padding_enabled = false) : string
++ public static function unwrap(string $kek, string $key, bool $padding_enabled = true) : string
+ {
+ $P = mb_str_split($key, 8, '8bit');
+ $A = $P[0];
+
+
+8) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:64 [M] MBString
+
+--- Original
++++ New
+@@ @@
+ */
+ public static function unwrap(string $kek, string $key, bool $padding_enabled = false) : string
+ {
+- $P = mb_str_split($key, 8, '8bit');
++ $P = str_split($key, 8);
+ $A = $P[0];
+ $N = count($P);
+ if ($N < 2) {
+
+
+9) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:110 [M] FalseValue
+
+--- Original
++++ New
+@@ @@
+ {
+ if ($padding_enabled === false) {
+ $bin = hex2bin('A6A6A6A6A6A6A6A6');
+- if ($bin === false) {
++ if ($bin === true) {
+ throw new InvalidArgumentException('Unable to convert the data');
+ }
+ return $bin;
+
+
+10) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:117 [M] MBString
+
+--- Original
++++ New
+@@ @@
+ }
+ return $bin;
+ }
+- $MLI = mb_strlen($key, '8bit');
++ $MLI = strlen($key);
+ $iv = hex2bin('A65959A6') . self::toXBits(32, $MLI);
+ $n = (int) ceil($MLI / 8);
+ $key = str_pad($key, 8 * $n, "\x00", STR_PAD_RIGHT);
+
+
+11) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:120 [M] DecrementInteger
+
+--- Original
++++ New
+@@ @@
+ }
+ $MLI = mb_strlen($key, '8bit');
+ $iv = hex2bin('A65959A6') . self::toXBits(32, $MLI);
+- $n = (int) ceil($MLI / 8);
++ $n = (int) ceil($MLI / 7);
+ $key = str_pad($key, 8 * $n, "\x00", STR_PAD_RIGHT);
+ return $iv;
+ }
+
+
+12) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:120 [M] IncrementInteger
+
+--- Original
++++ New
+@@ @@
+ }
+ $MLI = mb_strlen($key, '8bit');
+ $iv = hex2bin('A65959A6') . self::toXBits(32, $MLI);
+- $n = (int) ceil($MLI / 8);
++ $n = (int) ceil($MLI / 9);
+ $key = str_pad($key, 8 * $n, "\x00", STR_PAD_RIGHT);
+ return $iv;
+ }
+
+
+13) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:120 [M] RoundingFamily
+
+--- Original
++++ New
+@@ @@
+ }
+ $MLI = mb_strlen($key, '8bit');
+ $iv = hex2bin('A65959A6') . self::toXBits(32, $MLI);
+- $n = (int) ceil($MLI / 8);
++ $n = (int) round($MLI / 8);
+ $key = str_pad($key, 8 * $n, "\x00", STR_PAD_RIGHT);
+ return $iv;
+ }
+
+
+14) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:143 [M] MBString
+
+--- Original
++++ New
+@@ @@
+ if (hex2bin('A65959A6') !== self::getMSB($iv)) {
+ return false;
+ }
+- $n = mb_strlen($key, '8bit') / 8;
++ $n = strlen($key) / 8;
+ $MLI = (int) hexdec(bin2hex(ltrim(self::getLSB($iv), "\x00")));
+ if (!(8 * ($n - 1) < $MLI && $MLI <= 8 * $n)) {
+ return false;
+
+
+15) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:143 [M] IncrementInteger
+
+--- Original
++++ New
+@@ @@
+ if (hex2bin('A65959A6') !== self::getMSB($iv)) {
+ return false;
+ }
+- $n = mb_strlen($key, '8bit') / 8;
++ $n = mb_strlen($key, '8bit') / 9;
+ $MLI = (int) hexdec(bin2hex(ltrim(self::getLSB($iv), "\x00")));
+ if (!(8 * ($n - 1) < $MLI && $MLI <= 8 * $n)) {
+ return false;
+
+
+16) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:144 [M] UnwrapLtrim
+
+--- Original
++++ New
+@@ @@
+ return false;
+ }
+ $n = mb_strlen($key, '8bit') / 8;
+- $MLI = (int) hexdec(bin2hex(ltrim(self::getLSB($iv), "\x00")));
++ $MLI = (int) hexdec(bin2hex(self::getLSB($iv)));
+ if (!(8 * ($n - 1) < $MLI && $MLI <= 8 * $n)) {
+ return false;
+ }
+
+
+17) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:144 [M] CastInt
+
+--- Original
++++ New
+@@ @@
+ return false;
+ }
+ $n = mb_strlen($key, '8bit') / 8;
+- $MLI = (int) hexdec(bin2hex(ltrim(self::getLSB($iv), "\x00")));
++ $MLI = hexdec(bin2hex(ltrim(self::getLSB($iv), "\x00")));
+ if (!(8 * ($n - 1) < $MLI && $MLI <= 8 * $n)) {
+ return false;
+ }
+
+
+18) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:146 [M] DecrementInteger
+
+--- Original
++++ New
+@@ @@
+ }
+ $n = mb_strlen($key, '8bit') / 8;
+ $MLI = (int) hexdec(bin2hex(ltrim(self::getLSB($iv), "\x00")));
+- if (!(8 * ($n - 1) < $MLI && $MLI <= 8 * $n)) {
++ if (!(7 * ($n - 1) < $MLI && $MLI <= 8 * $n)) {
+ return false;
+ }
+ $b = 8 * $n - $MLI;
+
+
+19) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:146 [M] IncrementInteger
+
+--- Original
++++ New
+@@ @@
+ }
+ $n = mb_strlen($key, '8bit') / 8;
+ $MLI = (int) hexdec(bin2hex(ltrim(self::getLSB($iv), "\x00")));
+- if (!(8 * ($n - 1) < $MLI && $MLI <= 8 * $n)) {
++ if (!(9 * ($n - 1) < $MLI && $MLI <= 8 * $n)) {
+ return false;
+ }
+ $b = 8 * $n - $MLI;
+
+
+20) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:146 [M] IncrementInteger
+
+--- Original
++++ New
+@@ @@
+ }
+ $n = mb_strlen($key, '8bit') / 8;
+ $MLI = (int) hexdec(bin2hex(ltrim(self::getLSB($iv), "\x00")));
+- if (!(8 * ($n - 1) < $MLI && $MLI <= 8 * $n)) {
++ if (!(8 * ($n - 2) < $MLI && $MLI <= 8 * $n)) {
+ return false;
+ }
+ $b = 8 * $n - $MLI;
+
+
+21) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:146 [M] LessThan
+
+--- Original
++++ New
+@@ @@
+ }
+ $n = mb_strlen($key, '8bit') / 8;
+ $MLI = (int) hexdec(bin2hex(ltrim(self::getLSB($iv), "\x00")));
+- if (!(8 * ($n - 1) < $MLI && $MLI <= 8 * $n)) {
++ if (!(8 * ($n - 1) <= $MLI && $MLI <= 8 * $n)) {
+ return false;
+ }
+ $b = 8 * $n - $MLI;
+
+
+22) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:146 [M] DecrementInteger
+
+--- Original
++++ New
+@@ @@
+ }
+ $n = mb_strlen($key, '8bit') / 8;
+ $MLI = (int) hexdec(bin2hex(ltrim(self::getLSB($iv), "\x00")));
+- if (!(8 * ($n - 1) < $MLI && $MLI <= 8 * $n)) {
++ if (!(8 * ($n - 1) < $MLI && $MLI <= 7 * $n)) {
+ return false;
+ }
+ $b = 8 * $n - $MLI;
+
+
+23) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:146 [M] IncrementInteger
+
+--- Original
++++ New
+@@ @@
+ }
+ $n = mb_strlen($key, '8bit') / 8;
+ $MLI = (int) hexdec(bin2hex(ltrim(self::getLSB($iv), "\x00")));
+- if (!(8 * ($n - 1) < $MLI && $MLI <= 8 * $n)) {
++ if (!(8 * ($n - 1) < $MLI && $MLI <= 9 * $n)) {
+ return false;
+ }
+ $b = 8 * $n - $MLI;
+
+
+24) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:146 [M] LessThanOrEqualTo
+
+--- Original
++++ New
+@@ @@
+ }
+ $n = mb_strlen($key, '8bit') / 8;
+ $MLI = (int) hexdec(bin2hex(ltrim(self::getLSB($iv), "\x00")));
+- if (!(8 * ($n - 1) < $MLI && $MLI <= 8 * $n)) {
++ if (!(8 * ($n - 1) < $MLI && $MLI < 8 * $n)) {
+ return false;
+ }
+ $b = 8 * $n - $MLI;
+
+
+25) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:146 [M] LogicalAnd
+
+--- Original
++++ New
+@@ @@
+ }
+ $n = mb_strlen($key, '8bit') / 8;
+ $MLI = (int) hexdec(bin2hex(ltrim(self::getLSB($iv), "\x00")));
+- if (!(8 * ($n - 1) < $MLI && $MLI <= 8 * $n)) {
++ if (!(8 * ($n - 1) < $MLI || $MLI <= 8 * $n)) {
+ return false;
+ }
+ $b = 8 * $n - $MLI;
+
+
+26) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:150 [M] DecrementInteger
+
+--- Original
++++ New
+@@ @@
+ if (!(8 * ($n - 1) < $MLI && $MLI <= 8 * $n)) {
+ return false;
+ }
+- $b = 8 * $n - $MLI;
++ $b = 7 * $n - $MLI;
+ for ($i = 0; $i < $b; ++$i) {
+ if (mb_substr($key, $MLI + $i, 1, '8bit') !== "\x00") {
+ return false;
+
+
+27) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:150 [M] Multiplication
+
+--- Original
++++ New
+@@ @@
+ if (!(8 * ($n - 1) < $MLI && $MLI <= 8 * $n)) {
+ return false;
+ }
+- $b = 8 * $n - $MLI;
++ $b = 8 / $n - $MLI;
+ for ($i = 0; $i < $b; ++$i) {
+ if (mb_substr($key, $MLI + $i, 1, '8bit') !== "\x00") {
+ return false;
+
+
+28) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:151 [M] LessThanNegotiation
+
+--- Original
++++ New
+@@ @@
+ return false;
+ }
+ $b = 8 * $n - $MLI;
+- for ($i = 0; $i < $b; ++$i) {
++ for ($i = 0; $i >= $b; ++$i) {
+ if (mb_substr($key, $MLI + $i, 1, '8bit') !== "\x00") {
+ return false;
+ }
+
+
+29) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:151 [M] For_
+
+--- Original
++++ New
+@@ @@
+ return false;
+ }
+ $b = 8 * $n - $MLI;
+- for ($i = 0; $i < $b; ++$i) {
++ for ($i = 0; false; ++$i) {
+ if (mb_substr($key, $MLI + $i, 1, '8bit') !== "\x00") {
+ return false;
+ }
+
+
+30) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:152 [M] MBString
+
+--- Original
++++ New
+@@ @@
+ }
+ $b = 8 * $n - $MLI;
+ for ($i = 0; $i < $b; ++$i) {
+- if (mb_substr($key, $MLI + $i, 1, '8bit') !== "\x00") {
++ if (substr($key, $MLI + $i, 1) !== "\x00") {
+ return false;
+ }
+ }
+
+
+31) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:156 [M] MBString
+
+--- Original
++++ New
+@@ @@
+ return false;
+ }
+ }
+- $key = mb_substr($key, 0, $MLI, '8bit');
++ $key = substr($key, 0, $MLI);
+ return true;
+ }
+ private static function checkKeySize(string $key, bool $padding_enabled) : void
+
+
+32) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:166 [M] MBString
+
+--- Original
++++ New
+@@ @@
+ if ($key === '') {
+ throw new InvalidArgumentException('Bad key size');
+ }
+- if ($padding_enabled === false && mb_strlen($key, '8bit') % 8 !== 0) {
++ if ($padding_enabled === false && strlen($key) % 8 !== 0) {
+ throw new InvalidArgumentException('Bad key size');
+ }
+ }
+
+
+33) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:174 [M] FalseValue
+
+--- Original
++++ New
+@@ @@
+ private static function toXBits(int $bits, int $value) : string
+ {
+ $bin = hex2bin(str_pad(dechex($value), $bits / 4, '0', STR_PAD_LEFT));
+- if ($bin === false) {
++ if ($bin === true) {
+ throw new InvalidArgumentException('Unable to convert the data');
+ }
+ return $bin;
+
+
+34) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:183 [M] MBString
+
+--- Original
++++ New
+@@ @@
+ }
+ private static function getMSB(string $value) : string
+ {
+- return mb_substr($value, 0, mb_strlen($value, '8bit') / 2, '8bit');
++ return mb_substr($value, 0, strlen($value) / 2, '8bit');
+ }
+ private static function getLSB(string $value) : string
+ {
+
+
+35) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:183 [M] MBString
+
+--- Original
++++ New
+@@ @@
+ }
+ private static function getMSB(string $value) : string
+ {
+- return mb_substr($value, 0, mb_strlen($value, '8bit') / 2, '8bit');
++ return substr($value, 0, mb_strlen($value, '8bit') / 2);
+ }
+ private static function getLSB(string $value) : string
+ {
+
+
+36) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:188 [M] MBString
+
+--- Original
++++ New
+@@ @@
+ }
+ private static function getLSB(string $value) : string
+ {
+- return mb_substr($value, mb_strlen($value, '8bit') / 2, null, '8bit');
++ return mb_substr($value, strlen($value) / 2, null, '8bit');
+ }
+ private static function encrypt(string $kek, string $data) : string
+ {
+
+
+37) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:188 [M] MBString
+
+--- Original
++++ New
+@@ @@
+ }
+ private static function getLSB(string $value) : string
+ {
+- return mb_substr($value, mb_strlen($value, '8bit') / 2, null, '8bit');
++ return substr($value, mb_strlen($value, '8bit') / 2, null);
+ }
+ private static function encrypt(string $kek, string $data) : string
+ {
+
+
+38) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:194 [M] FalseValue
+
+--- Original
++++ New
+@@ @@
+ private static function encrypt(string $kek, string $data) : string
+ {
+ $result = openssl_encrypt($data, self::getMethod(), $kek, OPENSSL_ZERO_PADDING | OPENSSL_RAW_DATA);
+- if ($result === false) {
++ if ($result === true) {
+ throw new InvalidArgumentException('Unable to encrypt the data');
+ }
+ return $result;
+
+
+39) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:204 [M] FalseValue
+
+--- Original
++++ New
+@@ @@
+ private static function decrypt(string $kek, string $data) : string
+ {
+ $result = openssl_decrypt($data, self::getMethod(), $kek, OPENSSL_ZERO_PADDING | OPENSSL_RAW_DATA);
+- if ($result === false) {
++ if ($result === true) {
+ throw new InvalidArgumentException('Unable to decrypt the data');
+ }
+ return $result;
+ }
+ }
+
+
+Timed Out mutants:
+==================
+
+1) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:41 [M] Increment
+
+--- Original
++++ New
+@@ @@
+ $C[1] = self::getLSB($B);
+ } elseif ($N > 1) {
+ $R = $P;
+- for ($j = 0; $j <= 5; ++$j) {
++ for ($j = 0; $j <= 5; --$j) {
+ for ($i = 1; $i <= $N; ++$i) {
+ $B = self::encrypt($kek, $A . $R[$i - 1]);
+ $t = $i + $j * $N;
+
+
+2) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:77 [M] Decrement
+
+--- Original
++++ New
+@@ @@
+ $A = self::getMSB($B);
+ } else {
+ $R = $P;
+- for ($j = 5; $j >= 0; --$j) {
++ for ($j = 5; $j >= 0; ++$j) {
+ for ($i = $N - 1; $i >= 1; --$i) {
+ $t = $i + $j * ($N - 1);
+ $B = self::decrypt($kek, (self::toXBits(64, $t) ^ $A) . $R[$i]);
+
+
+Skipped mutants:
+================
+
+Not Covered mutants:
+====================
+
+1) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:111 [M] Throw_
+
+--- Original
++++ New
+@@ @@
+ if ($padding_enabled === false) {
+ $bin = hex2bin('A6A6A6A6A6A6A6A6');
+ if ($bin === false) {
+- throw new InvalidArgumentException('Unable to convert the data');
++ new InvalidArgumentException('Unable to convert the data');
+ }
+ return $bin;
+ }
+
+
+2) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:147 [M] FalseValue
+
+--- Original
++++ New
+@@ @@
+ $n = mb_strlen($key, '8bit') / 8;
+ $MLI = (int) hexdec(bin2hex(ltrim(self::getLSB($iv), "\x00")));
+ if (!(8 * ($n - 1) < $MLI && $MLI <= 8 * $n)) {
+- return false;
++ return true;
+ }
+ $b = 8 * $n - $MLI;
+ for ($i = 0; $i < $b; ++$i) {
+
+
+3) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:153 [M] FalseValue
+
+--- Original
++++ New
+@@ @@
+ $b = 8 * $n - $MLI;
+ for ($i = 0; $i < $b; ++$i) {
+ if (mb_substr($key, $MLI + $i, 1, '8bit') !== "\x00") {
+- return false;
++ return true;
+ }
+ }
+ $key = mb_substr($key, 0, $MLI, '8bit');
+
+
+4) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:175 [M] Throw_
+
+--- Original
++++ New
+@@ @@
+ {
+ $bin = hex2bin(str_pad(dechex($value), $bits / 4, '0', STR_PAD_LEFT));
+ if ($bin === false) {
+- throw new InvalidArgumentException('Unable to convert the data');
++ new InvalidArgumentException('Unable to convert the data');
+ }
+ return $bin;
+ }
+
+
+5) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:195 [M] Throw_
+
+--- Original
++++ New
+@@ @@
+ {
+ $result = openssl_encrypt($data, self::getMethod(), $kek, OPENSSL_ZERO_PADDING | OPENSSL_RAW_DATA);
+ if ($result === false) {
+- throw new InvalidArgumentException('Unable to encrypt the data');
++ new InvalidArgumentException('Unable to encrypt the data');
+ }
+ return $result;
+ }
+
+
+6) /home/florent/PhpstormProjects/aes-key-wrap/src/AESKW.php:205 [M] Throw_
+
+--- Original
++++ New
+@@ @@
+ {
+ $result = openssl_decrypt($data, self::getMethod(), $kek, OPENSSL_ZERO_PADDING | OPENSSL_RAW_DATA);
+ if ($result === false) {
+- throw new InvalidArgumentException('Unable to decrypt the data');
++ new InvalidArgumentException('Unable to decrypt the data');
+ }
+ return $result;
+ }
+ }
diff --git a/phpstan.neon b/phpstan.neon
index c03c598..e4d68ff 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -1,12 +1,11 @@
parameters:
- level: 7
+ level: max
paths:
- src
+ ignoreErrors:
+ -
+ message: '#Comparison operation .* between .* and 1 is always true\.#'
+ count: 3
+ path: src/AESKW.php
includes:
- - vendor/phpstan/phpstan-strict-rules/rules.neon
- - vendor/phpstan/phpstan-phpunit/extension.neon
- - vendor/phpstan/phpstan-phpunit/rules.neon
- - vendor/phpstan/phpstan-deprecation-rules/rules.neon
- - vendor/phpstan/phpstan-beberlei-assert/extension.neon
- vendor/phpstan/phpstan/conf/bleedingEdge.neon
- - vendor/thecodingmachine/phpstan-safe-rule/phpstan-safe-rule.neon
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index a0d3b34..faaf12b 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -14,15 +14,9 @@
./tests
-
-
-
- ./
-
- ./tests
- ./doc
- ./vendor
-
-
-
+
+
+ src
+
+
diff --git a/rector.php b/rector.php
new file mode 100644
index 0000000..762ee5b
--- /dev/null
+++ b/rector.php
@@ -0,0 +1,26 @@
+import(SetList::DEAD_CODE);
+ $containerConfigurator->import(SetList::PHP_80);
+ $containerConfigurator->import(SymfonySetList::SYMFONY_52);
+ $containerConfigurator->import(SymfonySetList::SYMFONY_CODE_QUALITY);
+ $parameters = $containerConfigurator->parameters();
+ $parameters->set(Option::PATHS, [__DIR__ . '/src', __DIR__ . '/tests']);
+ $parameters->set(Option::PHP_VERSION_FEATURES, PhpVersion::PHP_80);
+ $parameters->set(Option::AUTO_IMPORT_NAMES, true);
+ $parameters->set(Option::IMPORT_SHORT_CLASSES, false);
+ $parameters->set(Option::IMPORT_DOC_BLOCKS, false);
+
+ $services = $containerConfigurator->services();
+ $services->set(TypedPropertyRector::class);
+};
diff --git a/src/A128KW.php b/src/A128KW.php
index 531b4f8..73f97e1 100644
--- a/src/A128KW.php
+++ b/src/A128KW.php
@@ -2,18 +2,9 @@
declare(strict_types=1);
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2014-2020 Spomky-Labs
- *
- * This software may be modified and distributed under the terms
- * of the MIT license. See the LICENSE file for details.
- */
-
namespace AESKW;
-final class A128KW
+final class A128KW implements Wrapper
{
use AESKW;
diff --git a/src/A192KW.php b/src/A192KW.php
index b432046..773e182 100644
--- a/src/A192KW.php
+++ b/src/A192KW.php
@@ -2,18 +2,9 @@
declare(strict_types=1);
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2014-2020 Spomky-Labs
- *
- * This software may be modified and distributed under the terms
- * of the MIT license. See the LICENSE file for details.
- */
-
namespace AESKW;
-final class A192KW
+final class A192KW implements Wrapper
{
use AESKW;
diff --git a/src/A256KW.php b/src/A256KW.php
index 47123ea..5f3088a 100644
--- a/src/A256KW.php
+++ b/src/A256KW.php
@@ -2,18 +2,9 @@
declare(strict_types=1);
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2014-2020 Spomky-Labs
- *
- * This software may be modified and distributed under the terms
- * of the MIT license. See the LICENSE file for details.
- */
-
namespace AESKW;
-final class A256KW
+final class A256KW implements Wrapper
{
use AESKW;
diff --git a/src/AESKW.php b/src/AESKW.php
index 14403c0..b9c4a3f 100644
--- a/src/AESKW.php
+++ b/src/AESKW.php
@@ -2,23 +2,18 @@
declare(strict_types=1);
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2014-2020 Spomky-Labs
- *
- * This software may be modified and distributed under the terms
- * of the MIT license. See the LICENSE file for details.
- */
-
namespace AESKW;
use function count;
+use function hex2bin;
use InvalidArgumentException;
-use function Safe\hex2bin;
-use function Safe\mb_str_split;
-use function Safe\openssl_decrypt;
-use function Safe\openssl_encrypt;
+use function mb_str_split;
+use function openssl_decrypt;
+use function openssl_encrypt;
+use const OPENSSL_RAW_DATA;
+use const OPENSSL_ZERO_PADDING;
+use const STR_PAD_LEFT;
+use const STR_PAD_RIGHT;
trait AESKW
{
@@ -37,15 +32,15 @@ public static function wrap(string $kek, string $key, bool $padding_enabled = fa
$N = count($P);
$C = [];
- if (1 === $N) {
- $B = self::encrypt($kek, $A.$P[0]);
+ if ($N === 1) {
+ $B = self::encrypt($kek, $A . $P[0]);
$C[0] = self::getMSB($B);
$C[1] = self::getLSB($B);
- } elseif (1 < $N) {
+ } elseif ($N > 1) {
$R = $P;
for ($j = 0; $j <= 5; ++$j) {
for ($i = 1; $i <= $N; ++$i) {
- $B = self::encrypt($kek, $A.$R[$i - 1]);
+ $B = self::encrypt($kek, $A . $R[$i - 1]);
$t = $i + $j * $N;
$A = self::toXBits(64, $t) ^ self::getMSB($B);
$R[$i - 1] = self::getLSB($B);
@@ -70,11 +65,11 @@ public static function unwrap(string $kek, string $key, bool $padding_enabled =
$A = $P[0];
$N = count($P);
- if (2 > $N) {
+ if ($N < 2) {
throw new InvalidArgumentException('Bad data');
}
- if (2 === $N) {
- $B = self::decrypt($kek, $P[0].$P[1]);
+ if ($N === 2) {
+ $B = self::decrypt($kek, $P[0] . $P[1]);
$unwrapped = self::getLSB($B);
$A = self::getMSB($B);
} else {
@@ -82,7 +77,7 @@ public static function unwrap(string $kek, string $key, bool $padding_enabled =
for ($j = 5; $j >= 0; --$j) {
for ($i = $N - 1; $i >= 1; --$i) {
$t = $i + $j * ($N - 1);
- $B = self::decrypt($kek, (self::toXBits(64, $t) ^ $A).$R[$i]);
+ $B = self::decrypt($kek, (self::toXBits(64, $t) ^ $A) . $R[$i]);
$A = self::getMSB($B);
$R[$i] = self::getLSB($B);
}
@@ -91,7 +86,7 @@ public static function unwrap(string $kek, string $key, bool $padding_enabled =
$unwrapped = implode('', $R);
}
- if (false === self::checkInitialValue($unwrapped, $padding_enabled, $A)) {
+ if (self::checkInitialValue($unwrapped, $padding_enabled, $A) === false) {
throw new InvalidArgumentException('Integrity check failed!');
}
@@ -99,9 +94,9 @@ public static function unwrap(string $kek, string $key, bool $padding_enabled =
}
/**
- * The initial value used to wrap the key and check the integrity when unwrapped.
- * The RFC3394 set this value to 0xA6A6A6A6A6A6A6A6
- * The RFC5649 set this value to 0xA65959A6XXXXXXXX (The part with XXXXXXXX is the MLI, depends on the padding).
+ * The initial value used to wrap the key and check the integrity when unwrapped. The RFC3394 set this value to
+ * 0xA6A6A6A6A6A6A6A6 The RFC5649 set this value to 0xA65959A6XXXXXXXX (The part with XXXXXXXX is the MLI, depends
+ * on the padding).
*
* @param string $key The key
* @param bool $padding_enabled Enable padding (RFC5649)
@@ -110,12 +105,17 @@ public static function unwrap(string $kek, string $key, bool $padding_enabled =
*/
private static function getInitialValue(string &$key, bool $padding_enabled): string
{
- if (false === $padding_enabled) {
- return hex2bin('A6A6A6A6A6A6A6A6');
+ if ($padding_enabled === false) {
+ $bin = hex2bin('A6A6A6A6A6A6A6A6');
+ if ($bin === false) {
+ throw new InvalidArgumentException('Unable to convert the data');
+ }
+
+ return $bin;
}
$MLI = mb_strlen($key, '8bit');
- $iv = hex2bin('A65959A6').self::toXBits(32, $MLI);
+ $iv = hex2bin('A65959A6') . self::toXBits(32, $MLI);
$n = (int) ceil($MLI / 8);
$key = str_pad($key, 8 * $n, "\0", STR_PAD_RIGHT);
@@ -131,7 +131,7 @@ private static function checkInitialValue(string &$key, bool $padding_enabled, s
}
// The RFC3394 is required but the previous check is not satisfied => invalid
- if (false === $padding_enabled) {
+ if ($padding_enabled === false) {
return false;
}
@@ -143,13 +143,13 @@ private static function checkInitialValue(string &$key, bool $padding_enabled, s
$n = mb_strlen($key, '8bit') / 8;
$MLI = (int) hexdec(bin2hex(ltrim(self::getLSB($iv), "\0")));
- if (!(8 * ($n - 1) < $MLI && $MLI <= 8 * $n)) {
+ if (! (8 * ($n - 1) < $MLI && $MLI <= 8 * $n)) {
return false;
}
$b = 8 * $n - $MLI;
for ($i = 0; $i < $b; ++$i) {
- if ("\0" !== mb_substr($key, $MLI + $i, 1, '8bit')) {
+ if (mb_substr($key, $MLI + $i, 1, '8bit') !== "\0") {
return false;
}
}
@@ -160,17 +160,22 @@ private static function checkInitialValue(string &$key, bool $padding_enabled, s
private static function checkKeySize(string $key, bool $padding_enabled): void
{
- if ('' === $key) {
+ if ($key === '') {
throw new InvalidArgumentException('Bad key size');
}
- if (false === $padding_enabled && 0 !== mb_strlen($key, '8bit') % 8) {
+ if ($padding_enabled === false && mb_strlen($key, '8bit') % 8 !== 0) {
throw new InvalidArgumentException('Bad key size');
}
}
private static function toXBits(int $bits, int $value): string
{
- return hex2bin(str_pad(dechex($value), $bits / 4, '0', STR_PAD_LEFT));
+ $bin = hex2bin(str_pad(dechex($value), $bits / 4, '0', STR_PAD_LEFT));
+ if ($bin === false) {
+ throw new InvalidArgumentException('Unable to convert the data');
+ }
+
+ return $bin;
}
private static function getMSB(string $value): string
@@ -185,11 +190,21 @@ private static function getLSB(string $value): string
private static function encrypt(string $kek, string $data): string
{
- return openssl_encrypt($data, self::getMethod(), $kek, OPENSSL_ZERO_PADDING | OPENSSL_RAW_DATA);
+ $result = openssl_encrypt($data, self::getMethod(), $kek, OPENSSL_ZERO_PADDING | OPENSSL_RAW_DATA);
+ if ($result === false) {
+ throw new InvalidArgumentException('Unable to encrypt the data');
+ }
+
+ return $result;
}
private static function decrypt(string $kek, string $data): string
{
- return openssl_decrypt($data, self::getMethod(), $kek, OPENSSL_ZERO_PADDING | OPENSSL_RAW_DATA);
+ $result = openssl_decrypt($data, self::getMethod(), $kek, OPENSSL_ZERO_PADDING | OPENSSL_RAW_DATA);
+ if ($result === false) {
+ throw new InvalidArgumentException('Unable to decrypt the data');
+ }
+
+ return $result;
}
}
diff --git a/src/Wrapper.php b/src/Wrapper.php
new file mode 100644
index 0000000..446d811
--- /dev/null
+++ b/src/Wrapper.php
@@ -0,0 +1,26 @@
+ $value) {
$data[$key] = str_pad(dechex($value), 2, '0', STR_PAD_LEFT);
}
$data = hex2bin(implode('', $data));
$wrapped = A128KW::wrap($kek, $data);
- static::assertEquals(base64_decode('6KB707dM9YTIgHtLvtgWQ8mKwboJW3of9locizkDTHzBC2IlrT1oOQ', true), $wrapped);
+ static::assertSame(base64_decode('6KB707dM9YTIgHtLvtgWQ8mKwboJW3of9locizkDTHzBC2IlrT1oOQ', true), $wrapped);
$unwrapped = A128KW::unwrap($kek, $wrapped);
- static::assertEquals($data, $unwrapped);
+ static::assertSame($data, $unwrapped);
}
}
diff --git a/tests/One64BitBlockTest.php b/tests/One64BitBlockTest.php
index 2b5dbb1..238cf73 100644
--- a/tests/One64BitBlockTest.php
+++ b/tests/One64BitBlockTest.php
@@ -2,15 +2,6 @@
declare(strict_types=1);
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2014-2020 Spomky-Labs
- *
- * This software may be modified and distributed under the terms
- * of the MIT license. See the LICENSE file for details.
- */
-
namespace AESKW\Tests;
use AESKW\A128KW;
@@ -36,9 +27,9 @@ public function wrap64BitsKeyDataWith128BitKEK(): void
$data = hex2bin('0011223344556677');
$wrapped = A128KW::wrap($kek, $data);
- static::assertEquals(hex2bin('F4740052E82A225174CE86FBD7B805E7'), $wrapped);
+ static::assertSame(hex2bin('F4740052E82A225174CE86FBD7B805E7'), $wrapped);
$unwrapped = A128KW::unwrap($kek, $wrapped);
- static::assertEquals($data, $unwrapped);
+ static::assertSame($data, $unwrapped);
}
/**
@@ -50,9 +41,9 @@ public function wrap64BitsKeyDataWith192BitKEK(): void
$data = hex2bin('0011223344556677');
$wrapped = A192KW::wrap($kek, $data);
- static::assertEquals(hex2bin('DFE8FD5D1A3786A7351D385096CCFB29'), $wrapped);
+ static::assertSame(hex2bin('DFE8FD5D1A3786A7351D385096CCFB29'), $wrapped);
$unwrapped = A192KW::unwrap($kek, $wrapped);
- static::assertEquals($data, $unwrapped);
+ static::assertSame($data, $unwrapped);
}
/**
@@ -64,8 +55,8 @@ public function wrap64BitsKeyDataWith256BitKEK(): void
$data = hex2bin('0011223344556677');
$wrapped = A256KW::wrap($kek, $data);
- static::assertEquals(hex2bin('794314D454E3FDE1F661BD9F31FBFA31'), $wrapped);
+ static::assertSame(hex2bin('794314D454E3FDE1F661BD9F31FBFA31'), $wrapped);
$unwrapped = A256KW::unwrap($kek, $wrapped);
- static::assertEquals($data, $unwrapped);
+ static::assertSame($data, $unwrapped);
}
}
diff --git a/tests/Performance.php b/tests/Performance.php
index 7bc9ebb..4261be1 100644
--- a/tests/Performance.php
+++ b/tests/Performance.php
@@ -2,15 +2,6 @@
declare(strict_types=1);
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2014-2020 Spomky-Labs
- *
- * This software may be modified and distributed under the terms
- * of the MIT license. See the LICENSE file for details.
- */
-
namespace AESKW\Tests;
use AESKW\A128KW;
@@ -18,19 +9,18 @@
use AESKW\A256KW;
use function call_user_func_array;
use InvalidArgumentException;
+use const PHP_EOL;
/**
- * This class is used to check the performance of the library on the current platform.
- * You just have to call Performance::run();
- * By default, tests are performed 1000 times.
- * You can modify it by passing a positive integer as first argument:
- * Performance::run(10000);.
+ * This class is used to check the performance of the library on the current platform. You just have to call
+ * Performance::run(); By default, tests are performed 1000 times. You can modify it by passing a positive integer as
+ * first argument: Performance::run(10000);.
*/
final class Performance
{
public static function run(int $nb = 1000): void
{
- if (1 > $nb) {
+ if ($nb < 1) {
throw new InvalidArgumentException('You must perform at least 1 test.');
}
$cases = self::getData();
@@ -48,7 +38,7 @@ private static function wrap(int $nb, array $case): void
$padding = $case['padding'];
$time = self::do($class, 'wrap', $nb, $kek, $data, $padding);
- printf('%s: %f milliseconds/wrap'.PHP_EOL, $case['name'], $time);
+ printf('%s: %f milliseconds/wrap' . PHP_EOL, $case['name'], $time);
}
private static function unwrap(int $nb, array $case): void
@@ -59,7 +49,7 @@ private static function unwrap(int $nb, array $case): void
$padding = $case['padding'];
$time = self::do($class, 'unwrap', $nb, $kek, $result, $padding);
- printf('%s: %f milliseconds/unwrap'.PHP_EOL, $case['name'], $time);
+ printf('%s: %f milliseconds/unwrap' . PHP_EOL, $case['name'], $time);
}
/**
diff --git a/tests/RFC3394Test.php b/tests/RFC3394Test.php
index 1fae988..f9aba27 100644
--- a/tests/RFC3394Test.php
+++ b/tests/RFC3394Test.php
@@ -2,15 +2,6 @@
declare(strict_types=1);
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2014-2020 Spomky-Labs
- *
- * This software may be modified and distributed under the terms
- * of the MIT license. See the LICENSE file for details.
- */
-
namespace AESKW\Tests;
use AESKW\A128KW;
@@ -36,9 +27,9 @@ public function wrap128BitsKeyDataWith128BitKEK(): void
$data = hex2bin('00112233445566778899AABBCCDDEEFF');
$wrapped = A128KW::wrap($kek, $data);
- static::assertEquals(hex2bin('1FA68B0A8112B447AEF34BD8FB5A7B829D3E862371D2CFE5'), $wrapped);
+ static::assertSame(hex2bin('1FA68B0A8112B447AEF34BD8FB5A7B829D3E862371D2CFE5'), $wrapped);
$unwrapped = A128KW::unwrap($kek, $wrapped);
- static::assertEquals($data, $unwrapped);
+ static::assertSame($data, $unwrapped);
}
/**
@@ -50,9 +41,9 @@ public function wrap128BitsKeyDataWith192BitKEK(): void
$data = hex2bin('00112233445566778899AABBCCDDEEFF');
$wrapped = A192KW::wrap($kek, $data);
- static::assertEquals(hex2bin('96778B25AE6CA435F92B5B97C050AED2468AB8A17AD84E5D'), $wrapped);
+ static::assertSame(hex2bin('96778B25AE6CA435F92B5B97C050AED2468AB8A17AD84E5D'), $wrapped);
$unwrapped = A192KW::unwrap($kek, $wrapped);
- static::assertEquals($data, $unwrapped);
+ static::assertSame($data, $unwrapped);
}
/**
@@ -64,9 +55,9 @@ public function wrap128BitsKeyDataWith256BitKEK(): void
$data = hex2bin('00112233445566778899AABBCCDDEEFF');
$wrapped = A256KW::wrap($kek, $data);
- static::assertEquals(hex2bin('64E8C3F9CE0F5BA263E9777905818A2A93C8191E7D6E8AE7'), $wrapped);
+ static::assertSame(hex2bin('64E8C3F9CE0F5BA263E9777905818A2A93C8191E7D6E8AE7'), $wrapped);
$unwrapped = A256KW::unwrap($kek, $wrapped);
- static::assertEquals($data, $unwrapped);
+ static::assertSame($data, $unwrapped);
}
/**
@@ -78,9 +69,9 @@ public function wrap192BitsKeyDataWith192BitKEK(): void
$data = hex2bin('00112233445566778899AABBCCDDEEFF0001020304050607');
$wrapped = A192KW::wrap($kek, $data);
- static::assertEquals(hex2bin('031D33264E15D33268F24EC260743EDCE1C6C7DDEE725A936BA814915C6762D2'), $wrapped);
+ static::assertSame(hex2bin('031D33264E15D33268F24EC260743EDCE1C6C7DDEE725A936BA814915C6762D2'), $wrapped);
$unwrapped = A192KW::unwrap($kek, $wrapped);
- static::assertEquals($data, $unwrapped);
+ static::assertSame($data, $unwrapped);
}
/**
@@ -92,9 +83,9 @@ public function wrap192BitsKeyDataWith256BitKEK(): void
$data = hex2bin('00112233445566778899AABBCCDDEEFF0001020304050607');
$wrapped = A256KW::wrap($kek, $data);
- static::assertEquals(hex2bin('A8F9BC1612C68B3FF6E6F4FBE30E71E4769C8B80A32CB8958CD5D17D6B254DA1'), $wrapped);
+ static::assertSame(hex2bin('A8F9BC1612C68B3FF6E6F4FBE30E71E4769C8B80A32CB8958CD5D17D6B254DA1'), $wrapped);
$unwrapped = A256KW::unwrap($kek, $wrapped);
- static::assertEquals($data, $unwrapped);
+ static::assertSame($data, $unwrapped);
}
/**
@@ -106,8 +97,11 @@ public function wrap256BitsKeyDataWith256BitKEK(): void
$data = hex2bin('00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F');
$wrapped = A256KW::wrap($kek, $data);
- static::assertEquals(hex2bin('28C9F404C4B810F4CBCCB35CFB87F8263F5786E2D80ED326CBC7F0E71A99F43BFB988B9B7A02DD21'), $wrapped);
+ static::assertSame(
+ hex2bin('28C9F404C4B810F4CBCCB35CFB87F8263F5786E2D80ED326CBC7F0E71A99F43BFB988B9B7A02DD21'),
+ $wrapped
+ );
$unwrapped = A256KW::unwrap($kek, $wrapped);
- static::assertEquals($data, $unwrapped);
+ static::assertSame($data, $unwrapped);
}
}
diff --git a/tests/RFC5649Test.php b/tests/RFC5649Test.php
index dc2ba20..aae1152 100644
--- a/tests/RFC5649Test.php
+++ b/tests/RFC5649Test.php
@@ -2,15 +2,6 @@
declare(strict_types=1);
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2014-2020 Spomky-Labs
- *
- * This software may be modified and distributed under the terms
- * of the MIT license. See the LICENSE file for details.
- */
-
namespace AESKW\Tests;
use AESKW\A192KW;
@@ -34,9 +25,9 @@ public function wrap20BytesKeyDataWith192BitKEK(): void
$key = hex2bin('c37b7e6492584340bed12207808941155068f738');
$wrapped = A192KW::wrap($kek, $key, true);
- static::assertEquals(hex2bin('138bdeaa9b8fa7fc61f97742e72248ee5ae6ae5360d1ae6a5f54f373fa543b6a'), $wrapped);
+ static::assertSame(hex2bin('138bdeaa9b8fa7fc61f97742e72248ee5ae6ae5360d1ae6a5f54f373fa543b6a'), $wrapped);
$unwrapped = A192KW::unwrap($kek, $wrapped, true);
- static::assertEquals($key, $unwrapped);
+ static::assertSame($key, $unwrapped);
}
/**
@@ -48,8 +39,8 @@ public function wrap7BytesKeyDataWith192BitKEK(): void
$key = hex2bin('466f7250617369');
$wrapped = A192KW::wrap($kek, $key, true);
- static::assertEquals(hex2bin('afbeb0f07dfbf5419200f2ccb50bb24f'), $wrapped);
+ static::assertSame(hex2bin('afbeb0f07dfbf5419200f2ccb50bb24f'), $wrapped);
$unwrapped = A192KW::unwrap($kek, $wrapped, true);
- static::assertEquals($key, $unwrapped);
+ static::assertSame($key, $unwrapped);
}
}