PluginProbe ʕ •ᴥ•ʔ
Transferito: WP Migration / trunk
Transferito: WP Migration vtrunk
trunk 11.4.0 12.0.0 13.1.0 14.0.0 14.0.11 14.0.7 14.1.0 14.1.1 14.1.2 14.1.3 14.1.4
transferito / vendor / aws / aws-sdk-php / src / Crypto / Polyfill / ByteArray.php
transferito / vendor / aws / aws-sdk-php / src / Crypto / Polyfill Last commit date
AesGcm.php 11 months ago ByteArray.php 11 months ago Gmac.php 11 months ago Key.php 11 months ago NeedsTrait.php 11 months ago
ByteArray.php
260 lines
1 <?php
2 namespace Aws\Crypto\Polyfill;
3
4 /**
5 * Class ByteArray
6 * @package Aws\Crypto\Polyfill
7 */
8 class ByteArray extends \SplFixedArray
9 {
10 use NeedsTrait;
11
12 /**
13 * ByteArray constructor.
14 *
15 * @param int|string|int[] $size
16 * If you pass in an integer, it creates a ByteArray of that size.
17 * If you pass in a string or array, it converts it to an array of
18 * integers between 0 and 255.
19 * @throws \InvalidArgumentException
20 */
21 public function __construct($size = 0)
22 {
23 $arr = null;
24 // Integer? This behaves just like SplFixedArray.
25 if (\is_array($size)) {
26 // Array? We need to pass the count to parent::__construct() then populate
27 $arr = $size;
28 $size = \count($arr);
29 } elseif (\is_string($size)) {
30 // We need to avoid mbstring.func_overload
31 if (\is_callable('\\mb_str_split')) {
32 $tmp = \mb_str_split($size, 1, '8bit');
33 } else {
34 $tmp = \str_split($size, 1);
35 }
36 // Let's convert each character to an 8-bit integer and store in $arr
37 $arr = [];
38 if (!empty($tmp)) {
39 foreach ($tmp as $t) {
40 if (strlen($t) < 1) {
41 continue;
42 }
43 $arr []= \unpack('C', $t)[1] & 0xff;
44 }
45 }
46 $size = \count($arr);
47 } elseif ($size instanceof ByteArray) {
48 $arr = $size->toArray();
49 $size = $size->count();
50 } elseif (!\is_int($size)) {
51 throw new \InvalidArgumentException(
52 'Argument must be an integer, string, or array of integers.'
53 );
54 }
55
56 parent::__construct($size);
57
58 if (!empty($arr)) {
59 // Populate this object with values from constructor argument
60 foreach ($arr as $i => $v) {
61 $this->offsetSet($i, $v);
62 }
63 } else {
64 // Initialize to zero.
65 for ($i = 0; $i < $size; ++$i) {
66 $this->offsetSet($i, 0);
67 }
68 }
69 }
70
71 /**
72 * Encode an integer into a byte array. 32-bit (unsigned), big endian byte order.
73 *
74 * @param int $num
75 * @return self
76 */
77 public static function enc32be($num)
78 {
79 return new ByteArray(\pack('N', $num));
80 }
81
82 /**
83 * @param ByteArray $other
84 * @return bool
85 */
86 public function equals(ByteArray $other)
87 {
88 if ($this->count() !== $other->count()) {
89 return false;
90 }
91 $d = 0;
92 for ($i = $this->count() - 1; $i >= 0; --$i) {
93 $d |= $this[$i] ^ $other[$i];
94 }
95 return $d === 0;
96 }
97
98 /**
99 * @param ByteArray $array
100 * @return ByteArray
101 */
102 public function exclusiveOr(ByteArray $array)
103 {
104 self::needs(
105 $this->count() === $array->count(),
106 'Both ByteArrays must be equal size for exclusiveOr()'
107 );
108 $out = clone $this;
109 for ($i = 0; $i < $this->count(); ++$i) {
110 $out[$i] = $array[$i] ^ $out[$i];
111 }
112 return $out;
113 }
114
115 /**
116 * Returns a new ByteArray incremented by 1 (big endian byte order).
117 *
118 * @param int $increase
119 * @return self
120 */
121 public function getIncremented($increase = 1)
122 {
123 $clone = clone $this;
124 $index = $clone->count();
125 while ($index > 0) {
126 --$index;
127 $tmp = ($clone[$index] + $increase) & PHP_INT_MAX;
128 $clone[$index] = $tmp & 0xff;
129 $increase = $tmp >> 8;
130 }
131 return $clone;
132 }
133
134 /**
135 * Sets a value. See SplFixedArray for more.
136 *
137 * @param int $index
138 * @param int $newval
139 * @return void
140 */
141 #[\ReturnTypeWillChange]
142 public function offsetSet($index, $newval)
143 {
144 parent::offsetSet($index, $newval & 0xff);
145 }
146
147 /**
148 * Return a copy of this ByteArray, bitshifted to the right by 1.
149 * Used in Gmac.
150 *
151 * @return self
152 */
153 public function rshift()
154 {
155 $out = clone $this;
156 for ($j = $this->count() - 1; $j > 0; --$j) {
157 $out[$j] = (($out[$j - 1] & 1) << 7) | ($out[$j] >> 1);
158 }
159 $out[0] >>= 1;
160 return $out;
161 }
162
163 /**
164 * Constant-time conditional select. This is meant to read like a ternary operator.
165 *
166 * $z = ByteArray::select(1, $x, $y); // $z is equal to $x
167 * $z = ByteArray::select(0, $x, $y); // $z is equal to $y
168 *
169 * @param int $select
170 * @param ByteArray $left
171 * @param ByteArray $right
172 * @return ByteArray
173 */
174 public static function select($select, ByteArray $left, ByteArray $right)
175 {
176 self::needs(
177 $left->count() === $right->count(),
178 'Both ByteArrays must be equal size for select()'
179 );
180 $rightLength = $right->count();
181 $out = clone $right;
182 $mask = (-($select & 1)) & 0xff;
183 for ($i = 0; $i < $rightLength; $i++) {
184 $out[$i] = $out[$i] ^ (($left[$i] ^ $right[$i]) & $mask);
185 }
186 return $out;
187 }
188
189 /**
190 * Overwrite values of this ByteArray based on a separate ByteArray, with
191 * a given starting offset and length.
192 *
193 * See JavaScript's Uint8Array.set() for more information.
194 *
195 * @param ByteArray $input
196 * @param int $offset
197 * @param int|null $length
198 * @return self
199 */
200 public function set(ByteArray $input, $offset = 0, $length = null)
201 {
202 self::needs(
203 is_int($offset) && $offset >= 0,
204 'Offset must be a positive integer or zero'
205 );
206 if (is_null($length)) {
207 $length = $input->count();
208 }
209
210 $i = 0; $j = $offset;
211 while ($i < $length && $j < $this->count()) {
212 $this[$j] = $input[$i];
213 ++$i;
214 ++$j;
215 }
216 return $this;
217 }
218
219 /**
220 * Returns a slice of this ByteArray.
221 *
222 * @param int $start
223 * @param null $length
224 * @return self
225 */
226 public function slice($start = 0, $length = null)
227 {
228 return new ByteArray(\array_slice($this->toArray(), $start, $length));
229 }
230
231 /**
232 * Mutates the current state and sets all values to zero.
233 *
234 * @return void
235 */
236 public function zeroize()
237 {
238 for ($i = $this->count() - 1; $i >= 0; --$i) {
239 $this->offsetSet($i, 0);
240 }
241 }
242
243 /**
244 * Converts the ByteArray to a raw binary string.
245 *
246 * @return string
247 */
248 public function toString()
249 {
250 $count = $this->count();
251 if ($count === 0) {
252 return '';
253 }
254 $args = $this->toArray();
255 \array_unshift($args, \str_repeat('C', $count));
256 // constant-time, PHP <5.6 equivalent to pack('C*', ...$args);
257 return \call_user_func_array('\\pack', $args);
258 }
259 }
260