diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f23533..738ba05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [[v0.3.0](https://github.com/The-FireHub-Project/Runtime/compare/v0.2.6...v0.3.0)] – 2026-09-16 + +### Added +* Add PHP Hash utility wrappers and supporting exceptions by @dieselxxx + ## [[v0.2.6](https://github.com/The-FireHub-Project/Runtime/compare/v0.2.5...v0.2.6)] – 2026-09-11 ### Changed diff --git a/README.md b/README.md index 94b5bc6..8fd1745 100644 --- a/README.md +++ b/README.md @@ -7,12 +7,12 @@ PHP Runtime Foundation
release version @@ -22,25 +22,46 @@ /> -[![PHPStan](https://github.com/The-FireHub-Project/Runtime/actions/workflows/PHPStan.yml/badge.svg?branch=develop)](https://github.com/The-FireHub-Project/Runtime/actions/workflows/PHPStan.yml) -[![PHPUnit](https://github.com/The-FireHub-Project/Runtime/actions/workflows/PHPUnit.yml/badge.svg?branch=develop)](https://github.com/The-FireHub-Project/Runtime/actions/workflows/PHPUnit.yml) -[![Codecov](https://codecov.io/gh/The-FireHub-Project/Runtime/branch/develop/graph/badge.svg?token=XW2YEONF51)](https://app.codecov.io/gh/The-FireHub-Project/Runtime/tree/develop) -

- + + GitHub created at + GitHub last commit (branch) - + GitHub activity (branch) - + + GitHub contributors + GitHub commit difference between two branches + + GitHub top language + + GitHub repo size + + GitHub code size

@@ -54,47 +75,55 @@ Its role is to provide a consistent execution foundation between native PHP capa --- -## FireHub Icon Development Branch +## FireHub Icon Repository Purpose -⚠️ **This is the `develop` branch** +This repository provides a lightweight PHP runtime abstraction layer that wraps native PHP functionality into clean, consistent, and deterministic APIs. -- Unstable -- APIs may change without notice -- Not intended for production use +Its purpose is to reduce boilerplate and standardize common execution patterns across the FireHub ecosystem by offering ergonomic helper classes for arrays, strings, files, environment access, and other low-level runtime operations. -## FireHub Icon Branch Purpose +It is strictly focused on execution-level concerns and does not contain domain logic, business rules, or framework-level orchestration. It exists to improve developer productivity while preserving native PHP behavior and ensuring zero framework coupling. -The `develop` branch is the **primary integration branch** for all ongoing development. +## FireHub Icon Security -It serves as the staging area where: -- Feature branches are merged -- Bug fixes are integrated -- Experimental work is stabilized -- Code is prepared for upcoming releases +For security reporting and guidelines, please refer to our [SECURITY.md](https://github.com/The-FireHub-Project/.github/blob/master/.github/SECURITY.md) file. -All **release branches** are created **from `develop`**. +## FireHub Icon Community -## Stability Guarantee +![GitHub watchers](https://img.shields.io/github/watchers/The-FireHub-Project/Runtime?style=social) +![GitHub Repo stars](https://img.shields.io/github/stars/The-FireHub-Project/Runtime?style=social) +![GitHub forks](https://img.shields.io/github/forks/The-FireHub-Project/Runtime?style=social) -❌ No backward compatibility guarantee -❌ APIs may change without notice -❌ Behavior may be incomplete or inconsistent -❌ Breaking changes are expected +- Be sure to review the [Code of Conduct](https://github.com/The-FireHub-Project/.github/blob/master/.github/CODE_OF_CONDUCT.md). +- Read a [Contributing](https://github.com/The-FireHub-Project/.github/blob/master/.github/CONTRIBUTING.md) file to see how you can contribute to this project. +- Read our [Security policy](https://github.com/The-FireHub-Project/.github/blob/master/.github/SECURITY.md) file to see how you can report a vulnerability. +- Review the project [Governance model](https://github.com/The-FireHub-Project/.github/blob/master/.github/GOVERNANCE.md), including roles, decision-making, RFC process, and releases. -This branch is intended **only for contributors and advanced testers**. +## FireHub Icon Support -## FireHub Icon Composer Usage (Not Recommended) +

+ + GitHub in-progress issues + + GitHub total issues + + GitHub opened pull requests +

-For internal testing only: +For help with FireHub products, please refer to the following resources: -```json -{ - "require": { - "the-firehub-project/runtime": "dev-develop" - } -} -``` -⚠️ Never use dev-develop in production. +- **General questions & discussions**: [GitHub Discussions](https://github.com/orgs/The-FireHub-Project/discussions) +- **Bug reports & issues**: [Support](https://github.com/The-FireHub-Project/Runtime/issues) +- **Documentation & guides**: [FireHub Docs](https://the-firehub-project.github.io) +- **Commercial support** (Pro/Enterprise): contact your account manager ## FireHub Icon Authors and Contributors diff --git a/src/Exception/EmptyHashKeyException.php b/src/Exception/EmptyHashKeyException.php new file mode 100644 index 0000000..b95d016 --- /dev/null +++ b/src/Exception/EmptyHashKeyException.php @@ -0,0 +1,31 @@ + + * @copyright 2026-present The FireHub Project - All rights reserved + * @license https://opensource.org/license/Apache-2-0 Apache License, Version 2.0 + * + * @php-version >=8.3 + * @package Runtime + */ + +namespace FireHub\Runtime\Exception; + +use FireHub\Core\Exception\Runtime\InvalidArgumentException; + +/** + * ### Represents an empty hash key provided to an operation that requires a non-empty hash key + * @since 1.0.0 + */ +final class EmptyHashKeyException extends InvalidArgumentException { + + /** + * @inheritDoc + * + * @since 1.0.0 + */ + protected const string DEFAULT_MESSAGE = 'The provided hash key is empty.'; + +} \ No newline at end of file diff --git a/src/Exception/HashByteLengthException.php b/src/Exception/HashByteLengthException.php new file mode 100644 index 0000000..fce4359 --- /dev/null +++ b/src/Exception/HashByteLengthException.php @@ -0,0 +1,31 @@ + + * @copyright 2026-present The FireHub Project - All rights reserved + * @license https://opensource.org/license/Apache-2-0 Apache License, Version 2.0 + * + * @php-version >=8.3 + * @package Runtime + */ + +namespace FireHub\Runtime\Exception; + +use FireHub\Core\Exception\Runtime\InvalidArgumentException; + +/** + * ### Represents an invalid hash byte length provided to an operation that requires a valid hash byte length + * @since 1.0.0 + */ +final class HashByteLengthException extends InvalidArgumentException { + + /** + * @inheritDoc + * + * @since 1.0.0 + */ + protected const string DEFAULT_MESSAGE = 'The provided hash byte length is invalid.'; + +} \ No newline at end of file diff --git a/src/Exception/HashIterationException.php b/src/Exception/HashIterationException.php new file mode 100644 index 0000000..9e6fbfc --- /dev/null +++ b/src/Exception/HashIterationException.php @@ -0,0 +1,31 @@ + + * @copyright 2026-present The FireHub Project - All rights reserved + * @license https://opensource.org/license/Apache-2-0 Apache License, Version 2.0 + * + * @php-version >=8.3 + * @package Runtime + */ + +namespace FireHub\Runtime\Exception; + +use FireHub\Core\Exception\Runtime\InvalidArgumentException; + +/** + * ### Represents an invalid hash iteration provided to an operation that requires a valid hash iteration + * @since 1.0.0 + */ +final class HashIterationException extends InvalidArgumentException { + + /** + * @inheritDoc + * + * @since 1.0.0 + */ + protected const string DEFAULT_MESSAGE = 'The provided hash iteration is invalid.'; + +} \ No newline at end of file diff --git a/src/Hash.php b/src/Hash.php new file mode 100644 index 0000000..94b9217 --- /dev/null +++ b/src/Hash.php @@ -0,0 +1,301 @@ + + * @copyright 2026-present The FireHub Project - All rights reserved + * @license https://opensource.org/license/Apache-2-0 Apache License, Version 2.0 + * + * @php-version >=8.5 + * @package Runtime + */ + +namespace FireHub\Runtime; + +use FireHub\Core\Boundary\Runtime\NativeRuntime; +use FireHub\Runtime\Hash\Algorithm; +use FireHub\Runtime\Exception\ { + EmptyHashKeyException, HashByteLengthException, HashIterationException +}; +use SensitiveParameter, Throwable; + +use function hash; +use function hash_algos; +use function hash_equals; +use function hash_file; +use function hash_hkdf; +use function hash_hmac; +use function hash_hmac_algos; +use function hash_hmac_file; +use function hash_pbkdf2; + +/** + * ### PHP Runtime Hash Utilities + * + * Provides low-level wrappers for generating and comparing hashes using native PHP hash utilities while preserving + * native runtime behavior. + * + * This component exposes PHP hashing capabilities through a consistent FireHub Runtime API without altering native + * hashing semantics. + * @since 1.0.0 + */ +final class Hash extends NativeRuntime { + + /** + * ### Generates a hash value + * @since 1.0.0 + * + * @param \FireHub\Runtime\Hash\Algorithm $algorithm

+ * The hashing algorithm to use. + *

+ * @param string $data

+ * Message to be hashed. + *

+ * @param bool $binary [optional]

+ * When set to true, outputs raw binary data. false outputs lowercase hexits. + *

+ * @param array $options [optional]

+ * An associative array of hashing options. + *

+ * + * @return non-empty-string Returns a string containing the calculated message digest as lowercase hexits unless + * binary is set to true in which case the raw binary representation of the message digest is returned. + */ + public static function hash (Algorithm $algorithm, string $data, bool $binary = false, array $options = []):string { + + return hash($algorithm->value, $data, $binary, $options); + + } + + /** + * ### Generate a hash value using the contents of a given file + * @since 1.0.0 + * + * @param \FireHub\Runtime\Hash\Algorithm $algorithm

+ * The hashing algorithm to use. + *

+ * @param string $data

+ * Message to be hashed. + *

+ * @param bool $binary [optional]

+ * When set to true, outputs raw binary data. false outputs lowercase hexits. + *

+ * @param array $options [optional]

+ * An associative array of hashing options. + *

+ * + * @return non-empty-string|false Returns a string containing the calculated message digest as lowercase hexits + * unless binary is set to true in which case the raw binary representation of the message digest is returned, or + * false on failure. + */ + public static function file (Algorithm $algorithm, string $data, bool $binary = false, array $options = []):string|false { + + return hash_file($algorithm->value, $data, $binary, $options); + + } + + /** + * ### Gets available hashing algorithms + * @since 1.0.0 + * + * @return list Returns a numerically indexed array containing the list of supported hashing + * algorithms. + */ + public static function algorithms ():array { + + return hash_algos(); + + } + + /** + * ### Generate a keyed hash value using the HMAC method + * @since 1.0.0 + * + * @param \FireHub\Runtime\Hash\Algorithm $algorithm

+ * The hashing algorithm to use. + *

+ * @param string $data

+ * Message to be hashed. + *

+ * @param string $key

+ * Shared secret key used for generating the HMAC variant of the message digest + *

+ * @param bool $binary [optional]

+ * When set to true, outputs raw binary data. false outputs lowercase hexits. + *

+ * + * @return non-empty-string Returns a string containing the calculated message digest as lowercase hexits unless + * binary is set to true in which case the raw binary representation of the message digest is returned. + */ + public static function hmacHash (Algorithm $algorithm, string $data, #[SensitiveParameter] string $key, bool $binary = false):string { + + return hash_hmac($algorithm->value, $data, $key, $binary); + + } + + /** + * ### Generate a keyed hash value using the HMAC method + * @since 1.0.0 + * + * @param \FireHub\Runtime\Hash\Algorithm $algorithm

+ * The hashing algorithm to use. + *

+ * @param string $data

+ * Message to be hashed. + *

+ * @param string $key

+ * Shared secret key used for generating the HMAC variant of the message digest + *

+ * @param bool $binary [optional]

+ * When set to true, outputs raw binary data. false outputs lowercase hexits. + *

+ * + * @return non-empty-string|false Returns a string containing the calculated message digest as lowercase hexits + * unless binary is set to true in which case the raw binary representation of the message digest is returned. + * Returns false if the file filename cannot be read. + */ + public static function hmacFile (Algorithm $algorithm, string $data, #[SensitiveParameter] string $key, bool $binary = false):string|false { + + return hash_hmac_file($algorithm->value, $data, $key, $binary); + + } + + /** + * ### Gets available hashing algorithms suitable for hmac hashing + * @since 1.0.0 + * + * @return list Returns a numerically indexed array containing the list of supported hashing + * algorithms suitable for hmac hashing. + */ + public static function hmacAlgorithms ():array { + + return hash_hmac_algos(); + + } + + /** + * ### Timing attack safe string comparison + * @since 1.0.0 + * + * @param string $known

+ * The known string that must be kept secret. + *

+ * @param string $user

+ * The user-supplied string to compare against. + *

+ * + * @return bool Returns true when the two strings are equal, false otherwise. + */ + public static function equals (#[SensitiveParameter] string $known, #[SensitiveParameter] string $user):bool { + + return hash_equals($known, $user); + + } + + /** + * ### Generate a HKDF key derivation of a supplied key input + * @since 1.0.0 + * + * @param \FireHub\Runtime\Hash\Algorithm $algorithm

+ * The hashing algorithm to use. + *

+ * @param non-empty-string $key

+ * Input keying material (raw binary). + *

+ * @param non-negative-int $length [optional]

+ * Desired output length in bytes. + * + * Cannot be greater than 255 times the chosen hash function size. + * + * If length is 0, the output length will default to the chosen hash function size. + *

+ * @param string $info [optional]

+ * Application/context-specific info string. + *

+ * @param string $salt [optional]

+ * Salt to use during derivation. + * + * While optional, adding random salt significantly improves the strength of HKDF. + *

+ * + * @throws \FireHub\Runtime\Exception\EmptyHashKeyException If the key is empty. + * @throws \FireHub\Runtime\Exception\HashByteLengthException If the key is too long. + * + * @return non-empty-string Returns a string containing a raw binary representation of the derived key (also + * known as output keying material - OKM). + */ + public static function hkdf (Algorithm $algorithm, #[SensitiveParameter] string $key, int $length = 0, string $info = '', string $salt = ''):string { + + if ($key === '') throw new EmptyHashKeyException; + + try { + + return hash_hkdf($algorithm->value, $key, $length, $info, $salt); + + } catch (Throwable $e) { + + throw new HashByteLengthException($e->getMessage()); + } + + } + + /** + * ### Generates a PBKDF2 key derivation + * + * Generates a PBKDF2 key derivation using the specified hashing algorithm, password, salt, iteration count, + * and output length. + * @since 1.0.0 + * + * @param \FireHub\Runtime\Hash\Algorithm $algorithm

+ * The hashing algorithm to use. + *

+ * @param string $password

+ * The password to use for the derivation. + *

+ * @param string $salt

+ * The salt to use for the derivation. This value should be generated randomly. + *

+ * @param positive-int $iterations

+ * The number of internal iterations to perform for the derivation. + *

+ * @param non-negative-int $length

+ * The length of the output string. If binary is true this corresponds to the byte-length of the derived key, if + * binary is false this corresponds to twice the byte-length of the derived key (as every byte of the key is + * returned as two hexits). + * + * If 0 is passed, the entire output of the supplied algorithm is used. + *

+ * @param bool $binary

+ * Whether to return raw binary data instead of lowercase hexadecimal output. + *

+ * + * @throws \FireHub\Runtime\Exception\HashIterationException If the number of iterations is less than one. + * @throws \FireHub\Runtime\Exception\HashByteLengthException If the key is too long. + * + * @return non-empty-string Returns a string containing the derived key as lowercase hexits unless binary is set + * to true in which case the raw binary representation of the derived key is returned. + */ + public static function pbkdf2 (Algorithm $algorithm, #[SensitiveParameter] string $password, string $salt, int $iterations, int $length = 0, bool $binary = false):string { + + if ($iterations < 1) throw new HashIterationException("The number of iterations must be greater than zero."); + + try { + + return hash_pbkdf2( + $algorithm->value, + $password, + $salt, + $iterations, + $length, + $binary + ); + + } catch (Throwable $e) { + + throw new HashByteLengthException($e->getMessage()); + } + + } + +} \ No newline at end of file diff --git a/src/Hash/Algorithm.php b/src/Hash/Algorithm.php new file mode 100644 index 0000000..3c95257 --- /dev/null +++ b/src/Hash/Algorithm.php @@ -0,0 +1,474 @@ + + * @copyright 2026-present The FireHub Project - All rights reserved + * @license https://opensource.org/license/Apache-2-0 Apache License, Version 2.0 + * + * @php-version >=8.1 + * @package Runtime\Tests + */ + +namespace FireHub\Runtime\Hash; + +/** + * ### Hash Algorithm + * + * Defines hashing algorithms supported by the PHP hash extension. + * @since 1.0.0 + */ +enum Algorithm:string { + + + /* * ============================================================ + * MD + * ============================================================ */ + + /** + * ### MD2 message-digest algorithm + * @since 1.0.0 + */ + case MD2 = 'md2'; + + /** + * ### MD4 message-digest algorithm + * @since 1.0.0 + */ + case MD4 = 'md4'; + + /** + * ### MD5 message-digest algorithm + * @since 1.0.0 + */ + case MD5 = 'md5'; + + + /* * ============================================================ + * SHA-1 and SHA-2 + * ============================================================ */ + + /** + * ### SHA-1 secure hash algorithm + * @since 1.0.0 + */ + case SHA1 = 'sha1'; + + /** + * ### SHA-224 secure hash algorithm + * @since 1.0.0 + */ + case SHA224 = 'sha224'; + + /** + * ### SHA-256 secure hash algorithm + * @since 1.0.0 + */ + case SHA256 = 'sha256'; + + /** + * ### SHA-384 secure hash algorithm + * @since 1.0.0 + */ + case SHA384 = 'sha384'; + + /** + * ### SHA-512/224 secure hash algorithm + * @since 1.0.0 + */ + case SHA512_224 = 'sha512/224'; + + /** + * ### SHA-512/256 secure hash algorithm + * @since 1.0.0 + */ + case SHA512_256 = 'sha512/256'; + + /** + * ### SHA-512 secure hash algorithm + * @since 1.0.0 + */ + case SHA512 = 'sha512'; + + + /* * ============================================================ + * SHA-3 + * ============================================================ */ + + /** + * ### SHA3-224 secure hash algorithm + * @since 1.0.0 + */ + case SHA3_224 = 'sha3-224'; + + /** + * ### SHA3-256 secure hash algorithm + * @since 1.0.0 + */ + case SHA3_256 = 'sha3-256'; + + /** + * ### SHA3-384 secure hash algorithm + * @since 1.0.0 + */ + case SHA3_384 = 'sha3-384'; + + /** + * ### SHA3-512 secure hash algorithm + * @since 1.0.0 + */ + case SHA3_512 = 'sha3-512'; + + + /* * ============================================================ + * RIPEMD + * ============================================================ */ + + /** + * ### RIPEMD-128 message-digest algorithm + * @since 1.0.0 + */ + case RIPEMD128 = 'ripemd128'; + + /** + * ### RIPEMD-160 message-digest algorithm + * @since 1.0.0 + */ + case RIPEMD160 = 'ripemd160'; + + /** + * ### RIPEMD-256 message-digest algorithm + * @since 1.0.0 + */ + case RIPEMD256 = 'ripemd256'; + + /** + * ### RIPEMD-320 message-digest algorithm + * @since 1.0.0 + */ + case RIPEMD320 = 'ripemd320'; + + + /* * ============================================================ + * Whirlpool + * ============================================================ */ + + /** + * ### Whirlpool cryptographic hash algorithm + * @since 1.0.0 + */ + case WHIRLPOOL = 'whirlpool'; + + + /* * ============================================================ + * Tiger + * ============================================================ */ + + /** + * ### Tiger-128 hash algorithm with three passes + * @since 1.0.0 + */ + case TIGER128_3 = 'tiger128,3'; + + /** + * ### Tiger-160 hash algorithm with three passes + * @since 1.0.0 + */ + case TIGER160_3 = 'tiger160,3'; + + /** + * ### Tiger-192 hash algorithm with three passes + * @since 1.0.0 + */ + case TIGER192_3 = 'tiger192,3'; + + /** + * ### Tiger-128 hash algorithm with four passes + * @since 1.0.0 + */ + case TIGER128_4 = 'tiger128,4'; + + /** + * ### Tiger-160 hash algorithm with four passes + * @since 1.0.0 + */ + case TIGER160_4 = 'tiger160,4'; + + /** + * ### Tiger-192 hash algorithm with four passes + * @since 1.0.0 + */ + case TIGER192_4 = 'tiger192,4'; + + + /* * ============================================================ + * Snefru + * ============================================================ */ + + /** + * ### Snefru hash algorithm + * @since 1.0.0 + */ + case SNEFRU = 'snefru'; + + /** + * ### Snefru-256 hash algorithm + * @since 1.0.0 + */ + case SNEFRU256 = 'snefru256'; + + + /* * ============================================================ + * GOST + * ============================================================ */ + + /** + * ### GOST hash algorithm + * @since 1.0.0 + */ + case GOST = 'gost'; + + /** + * ### GOST CryptoPro hash algorithm + * @since 1.0.0 + */ + case GOST_CRYPTO = 'gost-crypto'; + + + /* * ============================================================ + * Checksums + * ============================================================ */ + + /** + * ### Adler-32 checksum algorithm + * @since 1.0.0 + */ + case ADLER32 = 'adler32'; + + /** + * ### CRC-32 checksum algorithm + * @since 1.0.0 + */ + case CRC32 = 'crc32'; + + /** + * ### CRC-32B checksum algorithm + * @since 1.0.0 + */ + case CRC32B = 'crc32b'; + + /** + * ### CRC-32C checksum algorithm + * @since 1.0.0 + */ + case CRC32C = 'crc32c'; + + + /* * ============================================================ + * FNV + * ============================================================ */ + + /** + * ### FNV-1 32-bit non-cryptographic hash algorithm + * @since 1.0.0 + */ + case FNV132 = 'fnv132'; + + /** + * ### FNV-1a 32-bit non-cryptographic hash algorithm + * @since 1.0.0 + */ + case FNV1A32 = 'fnv1a32'; + + /** + * ### FNV-1 64-bit non-cryptographic hash algorithm + * @since 1.0.0 + */ + case FNV164 = 'fnv164'; + + /** + * ### FNV-1a 64-bit non-cryptographic hash algorithm + * @since 1.0.0 + */ + case FNV1A64 = 'fnv1a64'; + + + /* * ============================================================ + * Jenkins + * ============================================================ */ + + /** + * ### Jenkins one-at-a-time non-cryptographic hash algorithm + * @since 1.0.0 + */ + case JOAAT = 'joaat'; + + + /* * ============================================================ + * MurmurHash + * ============================================================ */ + + /** + * ### MurmurHash3 32-bit hash algorithm + * @since 1.0.0 + */ + case MURMUR3A = 'murmur3a'; + + /** + * ### MurmurHash3 128-bit x86 hash algorithm + * @since 1.0.0 + */ + case MURMUR3C = 'murmur3c'; + + /** + * ### MurmurHash3 128-bit x64 hash algorithm + * @since 1.0.0 + */ + case MURMUR3F = 'murmur3f'; + + + /* * ============================================================ + * xxHash + * ============================================================ */ + + /** + * ### xxHash 32-bit non-cryptographic hash algorithm + * @since 1.0.0 + */ + case XXH32 = 'xxh32'; + + /** + * ### xxHash 64-bit non-cryptographic hash algorithm + * @since 1.0.0 + */ + case XXH64 = 'xxh64'; + + /** + * ### XXH3 64-bit non-cryptographic hash algorithm + * @since 1.0.0 + */ + case XXH3 = 'xxh3'; + + /** + * ### XXH3 128-bit non-cryptographic hash algorithm + * @since 1.0.0 + */ + case XXH128 = 'xxh128'; + + + /* * ============================================================ + * HAVAL + * ============================================================ */ + + /** + * ### HAVAL-128 hash algorithm with three passes + * @since 1.0.0 + */ + case HAVAL128_3 = 'haval128,3'; + + /** + * ### HAVAL-160 hash algorithm with three passes + * @since 1.0.0 + */ + case HAVAL160_3 = 'haval160,3'; + + /** + * ### HAVAL-192 hash algorithm with three passes + * @since 1.0.0 + */ + case HAVAL192_3 = 'haval192,3'; + + /** + * ### HAVAL-224 hash algorithm with three passes + * @since 1.0.0 + */ + case HAVAL224_3 = 'haval224,3'; + + /** + * ### HAVAL-256 hash algorithm with three passes + * @since 1.0.0 + */ + case HAVAL256_3 = 'haval256,3'; + + /** + * ### HAVAL-128 hash algorithm with four passes + * @since 1.0.0 + */ + case HAVAL128_4 = 'haval128,4'; + + /** + * ### HAVAL-160 hash algorithm with four passes + * @since 1.0.0 + */ + case HAVAL160_4 = 'haval160,4'; + + /** + * ### HAVAL-192 hash algorithm with four passes + * @since 1.0.0 + */ + case HAVAL192_4 = 'haval192,4'; + + /** + * ### HAVAL-224 hash algorithm with four passes + * @since 1.0.0 + */ + case HAVAL224_4 = 'haval224,4'; + + /** + * ### HAVAL-256 hash algorithm with four passes + * @since 1.0.0 + */ + case HAVAL256_4 = 'haval256,4'; + + /** + * ### HAVAL-128 hash algorithm with five passes + * @since 1.0.0 + */ + case HAVAL128_5 = 'haval128,5'; + + /** + * ### HAVAL-160 hash algorithm with five passes + * @since 1.0.0 + */ + case HAVAL160_5 = 'haval160,5'; + + /** + * ### HAVAL-192 hash algorithm with five passes + * @since 1.0.0 + */ + case HAVAL192_5 = 'haval192,5'; + + /** + * ### HAVAL-224 hash algorithm with five passes + * @since 1.0.0 + */ + case HAVAL224_5 = 'haval224,5'; + + /** + * ### HAVAL-256 hash algorithm with five passes + * @since 1.0.0 + */ + case HAVAL256_5 = 'haval256,5'; + + /** + * ### Checks whether the algorithm supports HMAC + * @since 1.0.0 + * + * @return bool True if the algorithm supports HMAC, false otherwise. + */ + public function supportsHmac ():bool { + + return match ($this) { + self::ADLER32, self::CRC32, self::CRC32B, self::CRC32C, + self::FNV132, self::FNV1A32, self::FNV164, self::FNV1A64, + self::JOAAT, + self::MURMUR3A, self::MURMUR3C, self::MURMUR3F, + self::XXH32, self::XXH64, self::XXH3, self::XXH128 + => false, + default => true + }; + + } + +} \ No newline at end of file