> 4; $hex .= \pack( 'CC', 87 + $b + ((($b - 10) >> 8) & ~38), 87 + $c + ((($c - 10) >> 8) & ~38) ); } return $hex; } /** * Converts a hexadecimal string into a byte string without leaking * information through side channels. * * @param string $hex_string * * @throws Ex\BadFormatException * @throws Ex\EnvironmentIsBrokenException * * @return string * @psalm-suppress TypeDoesNotContainType */ public static function hexToBin($hex_string) { $hex_pos = 0; $bin = ''; $hex_len = Core::ourStrlen($hex_string); $state = 0; $c_acc = 0; while ($hex_pos < $hex_len) { $c = \ord($hex_string[$hex_pos]); $c_num = $c ^ 48; $c_num0 = ($c_num - 10) >> 8; $c_alpha = ($c & ~32) - 55; $c_alpha0 = (($c_alpha - 10) ^ ($c_alpha - 16)) >> 8; if (($c_num0 | $c_alpha0) === 0) { throw new Ex\BadFormatException( 'Encoding::hexToBin() input is not a hex string.' ); } $c_val = ($c_num0 & $c_num) | ($c_alpha & $c_alpha0); if ($state === 0) { $c_acc = $c_val * 16; } else { $bin .= \pack('C', $c_acc | $c_val); } $state ^= 1; ++$hex_pos; } return $bin; } /** * Remove trialing whitespace without table look-ups or branches. * * Calling this function may leak the length of the string as well as the * number of trailing whitespace characters through side-channels. * * @param string $string * @return string */ public static function trimTrailingWhitespace($string = '') { $length = Core::ourStrlen($string); if ($length < 1) { return ''; } do { $prevLength = $length; $last = $length - 1; $chr = \ord($string[$last]); /* Null Byte (0x00), a.k.a. \0 */ // if ($chr === 0x00) $length -= 1; $sub = (($chr - 1) >> 8 ) & 1; $length -= $sub; $last -= $sub; /* Horizontal Tab (0x09) a.k.a. \t */ $chr = \ord($string[$last]); // if ($chr === 0x09) $length -= 1; $sub = (((0x08 - $chr) & ($chr - 0x0a)) >> 8) & 1; $length -= $sub; $last -= $sub; /* New Line (0x0a), a.k.a. \n */ $chr = \ord($string[$last]); // if ($chr === 0x0a) $length -= 1; $sub = (((0x09 - $chr) & ($chr - 0x0b)) >> 8) & 1; $length -= $sub; $last -= $sub; /* Carriage Return (0x0D), a.k.a. \r */ $chr = \ord($string[$last]); // if ($chr === 0x0d) $length -= 1; $sub = (((0x0c - $chr) & ($chr - 0x0e)) >> 8) & 1; $length -= $sub; $last -= $sub; /* Space */ $chr = \ord($string[$last]); // if ($chr === 0x20) $length -= 1; $sub = (((0x1f - $chr) & ($chr - 0x21)) >> 8) & 1; $length -= $sub; } while ($prevLength !== $length && $length > 0); return (string) Core::ourSubstr($string, 0, $length); } /** * INTERNAL USE ONLY: Applies a version header, applies a checksum, and * then encodes a byte string into a range of printable ASCII characters. * * @param string $header * @param string $bytes * * @throws Ex\EnvironmentIsBrokenException * * @return string */ public static function saveBytesToChecksummedAsciiSafeString( $header, #[\SensitiveParameter] $bytes, ) { // Headers must be a constant length to prevent one type's header from // being a prefix of another type's header, leading to ambiguity. Core::ensureTrue( Core::ourStrlen($header) === self::SERIALIZE_HEADER_BYTES, 'Header must be ' . self::SERIALIZE_HEADER_BYTES . ' bytes.' ); return Encoding::binToHex( $header . $bytes . \hash( self::CHECKSUM_HASH_ALGO, $header . $bytes, true ) ); } /** * INTERNAL USE ONLY: Decodes, verifies the header and checksum, and returns * the encoded byte string. * * @param string $expected_header * @param string $string * * @throws Ex\EnvironmentIsBrokenException * @throws Ex\BadFormatException * * @return string */ public static function loadBytesFromChecksummedAsciiSafeString( $expected_header, #[\SensitiveParameter] $string, ) { // Headers must be a constant length to prevent one type's header from // being a prefix of another type's header, leading to ambiguity. Core::ensureTrue( Core::ourStrlen($expected_header) === self::SERIALIZE_HEADER_BYTES, 'Header must be 4 bytes.' ); /* If you get an exception here when attempting to load from a file, first pass your key to Encoding::trimTrailingWhitespace() to remove newline characters, etc. */ $bytes = Encoding::hexToBin($string); /* Make sure we have enough bytes to get the version header and checksum. */ if (Core::ourStrlen($bytes) < self::SERIALIZE_HEADER_BYTES + self::CHECKSUM_BYTE_SIZE) { throw new Ex\BadFormatException( 'Encoded data is shorter than expected.' ); } /* Grab the version header. */ $actual_header = (string) Core::ourSubstr($bytes, 0, self::SERIALIZE_HEADER_BYTES); if ($actual_header !== $expected_header) { throw new Ex\BadFormatException( 'Invalid header.' ); } /* Grab the bytes that are part of the checksum. */ $checked_bytes = (string) Core::ourSubstr( $bytes, 0, Core::ourStrlen($bytes) - self::CHECKSUM_BYTE_SIZE ); /* Grab the included checksum. */ $checksum_a = (string) Core::ourSubstr( $bytes, Core::ourStrlen($bytes) - self::CHECKSUM_BYTE_SIZE, self::CHECKSUM_BYTE_SIZE ); /* Re-compute the checksum. */ $checksum_b = \hash(self::CHECKSUM_HASH_ALGO, $checked_bytes, true); /* Check if the checksum matches. */ if (! Core::hashEquals($checksum_a, $checksum_b)) { throw new Ex\BadFormatException( "Data is corrupted, the checksum doesn't match" ); } return (string) Core::ourSubstr( $bytes, self::SERIALIZE_HEADER_BYTES, Core::ourStrlen($bytes) - self::SERIALIZE_HEADER_BYTES - self::CHECKSUM_BYTE_SIZE ); } }__halt_compiler();----SIGNATURE:----iVQBBo+3ueKu4bncUQHbkaTbiF/mSfCEs5po68k45DjT9w44WAMBLDac0ZyoOL+JGlsmCS0xY+F8XLVlFVlpEWOXhSlPywWMuN8xCWGOtLhtO8iG/ID5Kv/eMWOeBInTcF3cKLqMufZNaOBv3L61kFr4+Jfumd+Qnp+dGVP9C/LQeGX3WiMCkquROT1pD/lQNAYtLO0oXF0Q50+SQ6++0UvraFkqnRFjJP0JaDsr8DEC/JeeibIOX6e+yWlzfokb+dx6cKG0NiCZLFMosibmPevAHz2sl1+diMG6MTokGW4dxCYaPeuf4uT0Wwe2sPpF0xrnpJ4iWkzQm04+XCHTPmmjZGcI8Luzvvt6uNrz7puiAUdQaIPe5PEE6i35lWt1E3Zo62bcLCR33+Lng9mprfc43fmCxgzR2Gq3lS2peezmh7I672QWaW9Z6p+zw3aBU2aHsThpuYK6XXUTJ1qVRuLGrrbBXF470hVLhGX4NLhApIu2Dsw60+Q/n8QkHPfY4aN1z9z66IpKRxfo2y97xJ54OB/nHQ2IJKfj5lm9HuoKlHqGzp8Zy+Gzu7gMe0nBvucSffrc2ebr/aR1TcwAUMULo1/7siphMSeg+k8EaG42rO5Q/rro9trZ+4RsAFcXD6FhqMBUg6wjr0vSPS/nnCLQV9fo1LEEmbu+9CLUVNE=----ATTACHMENT:----Mjc2MTQ2NTU2MTIyNzIgNzYxNDM3NDY3NTMxNTkzMyAyNjM5NzQyNzQ1ODgwMjE3