Completed
Push — master ( f7fb6b...e4d297 )
by Tony Karavasilev (Тони
15:27
created

Argon2   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 125
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 8
eloc 23
c 1
b 0
f 0
dl 0
loc 125
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A fetchAlgorithmVariation() 0 3 2
A validateVersion() 0 5 3
A fetchAlgorithmParameters() 0 6 1
A __construct() 0 7 2
1
<?php
2
3
/**
4
 * The Argon2 hashing algorithm class.
5
 */
6
7
namespace CryptoManana\Hashing;
8
9
use \CryptoManana\Core\Abstractions\MessageDigestion\AbstractHardwareResistantDerivation as StrongDerivationAlgorithm;
10
use \CryptoManana\Core\Interfaces\MessageDigestion\ComplexAlgorithmicCostInterface as ComplexAlgorithmicCostTuning;
11
use \CryptoManana\Core\Interfaces\MessageDigestion\AlgorithmVariationInterface as AlgorithmVariationSwitching;
12
use \CryptoManana\Core\Traits\MessageDigestion\ComplexAlgorithmicCostTrait as ComplexAlgorithmicCostTuningCapabilities;
13
use \CryptoManana\Core\Traits\MessageDigestion\AlgorithmVariationTrait as AlgorithmVariationSwitchingCapabilities;
14
15
/**
16
 * Class Argon2 - The Argon2 hashing algorithm object.
17
 *
18
 * @package CryptoManana\Hashing
19
 *
20
 * @mixin ComplexAlgorithmicCostTuningCapabilities
21
 *
22
 * @codeCoverageIgnore
23
 */
24
class Argon2 extends StrongDerivationAlgorithm implements ComplexAlgorithmicCostTuning, AlgorithmVariationSwitching
25
{
26
    /**
27
     * Algorithmic cost tuning complex capabilities.
28
     *
29
     * {@internal Reusable implementation of `ComplexAlgorithmicCostInterface`. }}
30
     */
31
    use ComplexAlgorithmicCostTuningCapabilities;
32
33
    /**
34
     * Algorithm variation switching capabilities.
35
     *
36
     * {@internal Reusable implementation of `AlgorithmVariationInterface`. }}
37
     */
38
    use AlgorithmVariationSwitchingCapabilities;
39
40
    /**
41
     * The internal name of the algorithm.
42
     */
43
    const ALGORITHM_NAME = 'argon2';
44
45
    /**
46
     * The internal maximum length in bytes of the raw output digest for the algorithm.
47
     *
48
     * @internal For the current algorithm: `PHP_INT_MAX`
49
     */
50
    const ALGORITHM_MAXIMUM_OUTPUT = PHP_INT_MAX;
51
52
    /**
53
     * The Argon2i variation setting constant.
54
     *
55
     * @see AlgorithmVariationSwitching::VERSION_ONE
56
     *
57
     * @internal Same as `Argon2::VERSION_ONE`.
58
     */
59
    const VERSION_I = 1;
60
61
    /**
62
     * The Argon2id variation setting constant.
63
     *
64
     * @see AlgorithmVariationSwitching::VERSION_TWO
65
     *
66
     * @internal Same as `Argon2::VERSION_TWO`.
67
     */
68
    const VERSION_ID = 2;
69
70
    /**
71
     * The internal algorithm variation property storage.
72
     *
73
     * @var int The algorithm variation value.
74
     */
75
    protected $algorithmVariation = self::VERSION_I;
76
77
    /**
78
     * The digestion internal computational memory cost property storage.
79
     *
80
     * @var int The algorithmic memory cost value.
81
     */
82
    protected $memoryCost = PASSWORD_ARGON2_DEFAULT_MEMORY_COST;
83
84
    /**
85
     * The digestion internal computational time cost property storage.
86
     *
87
     * @var int The algorithmic time cost value.
88
     */
89
    protected $timeCost = PASSWORD_ARGON2_DEFAULT_TIME_COST;
90
91
    /**
92
     * The digestion internal computational thread cost property storage.
93
     *
94
     * @var int The algorithmic thread cost value.
95
     */
96
    protected $threadsCost = PASSWORD_ARGON2_DEFAULT_THREADS;
97
98
99
    /**
100
     * Fetch the correctly formatted internal variation for digestion.
101
     *
102
     * @return int|string The chosen variation for password hashing.
103
     */
104
    protected function fetchAlgorithmVariation()
105
    {
106
        return ($this->algorithmVariation === self::VERSION_ID) ? PASSWORD_ARGON2ID : PASSWORD_ARGON2I;
107
    }
108
109
    /**
110
     * Fetch the correctly formatted internal parameters for digestion.
111
     *
112
     * @return array The chosen parameters for password hashing.
113
     */
114
    protected function fetchAlgorithmParameters()
115
    {
116
        return [
117
            'memory_cost' => $this->memoryCost,
118
            'time_cost ' => $this->timeCost,
119
            'threads' => $this->threadsCost,
120
        ];
121
    }
122
123
    /**
124
     * Internal method for version range validation.
125
     *
126
     * @param int $version The version for validation checks.
127
     *
128
     * @throws \Exception Validation errors.
129
     */
130
    protected function validateVersion($version)
131
    {
132
        if (!in_array(($version === self::VERSION_ID) ? PASSWORD_ARGON2ID : PASSWORD_ARGON2I, password_algos(), true)) {
133
            throw new \RuntimeException(
134
                'The Argon2 algorithm variation is not supported under the current system configuration.'
135
            );
136
        }
137
    }
138
139
    /**
140
     * Password-based key derivation algorithm constructor.
141
     */
142
    public function __construct()
143
    {
144
        parent::__construct();
145
146
        if (!in_array(PASSWORD_ARGON2I, password_algos(), true)) {
147
            throw new \RuntimeException(
148
                'The Argon2 algorithm is not supported under the current system configuration.'
149
            );
150
        }
151
    }
152
}
153