pax_global_header00006660000000000000000000000064135606163750014526gustar00rootroot0000000000000052 comment=47a1cedd2e4d52688eb8c96469c05ebc8fd28fa2 constant_time_encoding-2.3.0/000077500000000000000000000000001356061637500162455ustar00rootroot00000000000000constant_time_encoding-2.3.0/.gitignore000066400000000000000000000000161356061637500202320ustar00rootroot00000000000000.idea/ vendor/constant_time_encoding-2.3.0/.travis.yml000066400000000000000000000005501356061637500203560ustar00rootroot00000000000000language: php sudo: false matrix: fast_finish: true include: - php: "7.0" - php: "7.1" - php: "7.2" - php: "7.3" - php: "7.4snapshot" - php: "nightly" allow_failures: - php: "nightly" - php: "7.4snapshot" install: - composer self-update - composer update script: - vendor/bin/phpunit - vendor/bin/psalm constant_time_encoding-2.3.0/LICENSE.txt000066400000000000000000000045451356061637500201000ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2016 - 2018 Paragon Initiative Enterprises Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------ This library was based on the work of Steve "Sc00bz" Thomas. ------------------------------------------------------------------------------ The MIT License (MIT) Copyright (c) 2014 Steve Thomas Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. constant_time_encoding-2.3.0/README.md000066400000000000000000000061121356061637500175240ustar00rootroot00000000000000# Constant-Time Encoding [![Build Status](https://travis-ci.org/paragonie/constant_time_encoding.svg?branch=master)](https://travis-ci.org/paragonie/constant_time_encoding) [![Latest Stable Version](https://poser.pugx.org/paragonie/constant_time_encoding/v/stable)](https://packagist.org/packages/paragonie/constant_time_encoding) [![Latest Unstable Version](https://poser.pugx.org/paragonie/constant_time_encoding/v/unstable)](https://packagist.org/packages/paragonie/constant_time_encoding) [![License](https://poser.pugx.org/paragonie/constant_time_encoding/license)](https://packagist.org/packages/paragonie/constant_time_encoding) [![Downloads](https://img.shields.io/packagist/dt/paragonie/constant_time_encoding.svg)](https://packagist.org/packages/paragonie/constant_time_encoding) Based on the [constant-time base64 implementation made by Steve "Sc00bz" Thomas](https://github.com/Sc00bz/ConstTimeEncoding), this library aims to offer character encoding functions that do not leak information about what you are encoding/decoding via processor cache misses. Further reading on [cache-timing attacks](http://blog.ircmaxell.com/2014/11/its-all-about-time.html). Our fork offers the following enchancements: * `mbstring.func_overload` resistance * Unit tests * Composer- and Packagist-ready * Base16 encoding * Base32 encoding * Uses `pack()` and `unpack()` instead of `chr()` and `ord()` ## PHP Version Requirements Version 2 of this library should work on **PHP 7** or newer. For PHP 5 support, see [the v1.x branch](https://github.com/paragonie/constant_time_encoding/tree/v1.x). If you are adding this as a dependency to a project intended to work on both PHP 5 and PHP 7, please set the required version to `^1|^2` instead of just `^1` or `^2`. ## How to Install ```sh composer require paragonie/constant_time_encoding ``` ## How to Use ```php use \ParagonIE\ConstantTime\Encoding; // possibly (if applicable): // require 'vendor/autoload.php'; $data = random_bytes(32); echo Encoding::base64Encode($data), "\n"; echo Encoding::base32EncodeUpper($data), "\n"; echo Encoding::base32Encode($data), "\n"; echo Encoding::hexEncode($data), "\n"; echo Encoding::hexEncodeUpper($data), "\n"; ``` Example output: ``` 1VilPkeVqirlPifk5scbzcTTbMT2clp+Zkyv9VFFasE= 2VMKKPSHSWVCVZJ6E7SONRY3ZXCNG3GE6ZZFU7TGJSX7KUKFNLAQ==== 2vmkkpshswvcvzj6e7sonry3zxcng3ge6zzfu7tgjsx7kukfnlaq==== d558a53e4795aa2ae53e27e4e6c71bcdc4d36cc4f6725a7e664caff551456ac1 D558A53E4795AA2AE53E27E4E6C71BDCC4D36CC4F6725A7E664CAFF551456AC1 ``` If you only need a particular variant, you can just reference the required class like so: ```php use \ParagonIE\ConstantTime\Base64; use \ParagonIE\ConstantTime\Base32; $data = random_bytes(32); echo Base64::encode($data), "\n"; echo Base32::encode($data), "\n"; ``` Example output: ``` 1VilPkeVqirlPifk5scbzcTTbMT2clp+Zkyv9VFFasE= 2vmkkpshswvcvzj6e7sonry3zxcng3ge6zzfu7tgjsx7kukfnlaq==== ``` ## Support Contracts If your company uses this library in their products or services, you may be interested in [purchasing a support contract from Paragon Initiative Enterprises](https://paragonie.com/enterprise). constant_time_encoding-2.3.0/composer.json000066400000000000000000000023071356061637500207710ustar00rootroot00000000000000{ "name": "paragonie/constant_time_encoding", "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", "keywords": [ "base64", "encoding", "rfc4648", "base32", "base16", "hex", "bin2hex", "hex2bin", "base64_encode", "base64_decode", "base32_encode", "base32_decode" ], "license": "MIT", "type": "library", "authors": [ { "name": "Paragon Initiative Enterprises", "email": "security@paragonie.com", "homepage": "https://paragonie.com", "role": "Maintainer" }, { "name": "Steve 'Sc00bz' Thomas", "email": "steve@tobtu.com", "homepage": "https://www.tobtu.com", "role": "Original Developer" } ], "support": { "issues": "https://github.com/paragonie/constant_time_encoding/issues", "email": "info@paragonie.com", "source": "https://github.com/paragonie/constant_time_encoding" }, "require": { "php": "^7|^8" }, "require-dev": { "phpunit/phpunit": "^6|^7", "vimeo/psalm": "^1|^2|^3" }, "autoload": { "psr-4": { "ParagonIE\\ConstantTime\\": "src/" } } } constant_time_encoding-2.3.0/phpunit.xml.dist000066400000000000000000000013571356061637500214260ustar00rootroot00000000000000 ./tests ./src constant_time_encoding-2.3.0/psalm.xml000066400000000000000000000002441356061637500201030ustar00rootroot00000000000000 constant_time_encoding-2.3.0/src/000077500000000000000000000000001356061637500170345ustar00rootroot00000000000000constant_time_encoding-2.3.0/src/Base32.php000066400000000000000000000372621356061637500205760ustar00rootroot00000000000000 96 && $src < 123) $ret += $src - 97 + 1; // -64 $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 96); // if ($src > 0x31 && $src < 0x38) $ret += $src - 24 + 1; // -23 $ret += (((0x31 - $src) & ($src - 0x38)) >> 8) & ($src - 23); return $ret; } /** * Uses bitwise operators instead of table-lookups to turn 5-bit integers * into 8-bit integers. * * Uppercase variant. * * @param int $src * @return int */ protected static function decode5BitsUpper(int $src): int { $ret = -1; // if ($src > 64 && $src < 91) $ret += $src - 65 + 1; // -64 $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64); // if ($src > 0x31 && $src < 0x38) $ret += $src - 24 + 1; // -23 $ret += (((0x31 - $src) & ($src - 0x38)) >> 8) & ($src - 23); return $ret; } /** * Uses bitwise operators instead of table-lookups to turn 8-bit integers * into 5-bit integers. * * @param int $src * @return string */ protected static function encode5Bits(int $src): string { $diff = 0x61; // if ($src > 25) $ret -= 72; $diff -= ((25 - $src) >> 8) & 73; return \pack('C', $src + $diff); } /** * Uses bitwise operators instead of table-lookups to turn 8-bit integers * into 5-bit integers. * * Uppercase variant. * * @param int $src * @return string */ protected static function encode5BitsUpper(int $src): string { $diff = 0x41; // if ($src > 25) $ret -= 40; $diff -= ((25 - $src) >> 8) & 41; return \pack('C', $src + $diff); } /** * Base32 decoding * * @param string $src * @param bool $upper * @param bool $strictPadding * @return string * @throws \TypeError * @psalm-suppress RedundantCondition */ protected static function doDecode(string $src, bool $upper = false, bool $strictPadding = false): string { // We do this to reduce code duplication: $method = $upper ? 'decode5BitsUpper' : 'decode5Bits'; // Remove padding $srcLen = Binary::safeStrlen($src); if ($srcLen === 0) { return ''; } if ($strictPadding) { if (($srcLen & 7) === 0) { for ($j = 0; $j < 7; ++$j) { if ($src[$srcLen - 1] === '=') { $srcLen--; } else { break; } } } if (($srcLen & 7) === 1) { throw new \RangeException( 'Incorrect padding' ); } } else { $src = \rtrim($src, '='); $srcLen = Binary::safeStrlen($src); } $err = 0; $dest = ''; // Main loop (no padding): for ($i = 0; $i + 8 <= $srcLen; $i += 8) { /** @var array $chunk */ $chunk = \unpack('C*', Binary::safeSubstr($src, $i, 8)); /** @var int $c0 */ $c0 = static::$method($chunk[1]); /** @var int $c1 */ $c1 = static::$method($chunk[2]); /** @var int $c2 */ $c2 = static::$method($chunk[3]); /** @var int $c3 */ $c3 = static::$method($chunk[4]); /** @var int $c4 */ $c4 = static::$method($chunk[5]); /** @var int $c5 */ $c5 = static::$method($chunk[6]); /** @var int $c6 */ $c6 = static::$method($chunk[7]); /** @var int $c7 */ $c7 = static::$method($chunk[8]); $dest .= \pack( 'CCCCC', (($c0 << 3) | ($c1 >> 2) ) & 0xff, (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff, (($c3 << 4) | ($c4 >> 1) ) & 0xff, (($c4 << 7) | ($c5 << 2) | ($c6 >> 3)) & 0xff, (($c6 << 5) | ($c7 ) ) & 0xff ); $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5 | $c6 | $c7) >> 8; } // The last chunk, which may have padding: if ($i < $srcLen) { /** @var array $chunk */ $chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i)); /** @var int $c0 */ $c0 = static::$method($chunk[1]); if ($i + 6 < $srcLen) { /** @var int $c1 */ $c1 = static::$method($chunk[2]); /** @var int $c2 */ $c2 = static::$method($chunk[3]); /** @var int $c3 */ $c3 = static::$method($chunk[4]); /** @var int $c4 */ $c4 = static::$method($chunk[5]); /** @var int $c5 */ $c5 = static::$method($chunk[6]); /** @var int $c6 */ $c6 = static::$method($chunk[7]); $dest .= \pack( 'CCCC', (($c0 << 3) | ($c1 >> 2) ) & 0xff, (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff, (($c3 << 4) | ($c4 >> 1) ) & 0xff, (($c4 << 7) | ($c5 << 2) | ($c6 >> 3)) & 0xff ); $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5 | $c6) >> 8; } elseif ($i + 5 < $srcLen) { /** @var int $c1 */ $c1 = static::$method($chunk[2]); /** @var int $c2 */ $c2 = static::$method($chunk[3]); /** @var int $c3 */ $c3 = static::$method($chunk[4]); /** @var int $c4 */ $c4 = static::$method($chunk[5]); /** @var int $c5 */ $c5 = static::$method($chunk[6]); $dest .= \pack( 'CCCC', (($c0 << 3) | ($c1 >> 2) ) & 0xff, (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff, (($c3 << 4) | ($c4 >> 1) ) & 0xff, (($c4 << 7) | ($c5 << 2) ) & 0xff ); $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5) >> 8; } elseif ($i + 4 < $srcLen) { /** @var int $c1 */ $c1 = static::$method($chunk[2]); /** @var int $c2 */ $c2 = static::$method($chunk[3]); /** @var int $c3 */ $c3 = static::$method($chunk[4]); /** @var int $c4 */ $c4 = static::$method($chunk[5]); $dest .= \pack( 'CCC', (($c0 << 3) | ($c1 >> 2) ) & 0xff, (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff, (($c3 << 4) | ($c4 >> 1) ) & 0xff ); $err |= ($c0 | $c1 | $c2 | $c3 | $c4) >> 8; } elseif ($i + 3 < $srcLen) { /** @var int $c1 */ $c1 = static::$method($chunk[2]); /** @var int $c2 */ $c2 = static::$method($chunk[3]); /** @var int $c3 */ $c3 = static::$method($chunk[4]); $dest .= \pack( 'CC', (($c0 << 3) | ($c1 >> 2) ) & 0xff, (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff ); $err |= ($c0 | $c1 | $c2 | $c3) >> 8; } elseif ($i + 2 < $srcLen) { /** @var int $c1 */ $c1 = static::$method($chunk[2]); /** @var int $c2 */ $c2 = static::$method($chunk[3]); $dest .= \pack( 'CC', (($c0 << 3) | ($c1 >> 2) ) & 0xff, (($c1 << 6) | ($c2 << 1) ) & 0xff ); $err |= ($c0 | $c1 | $c2) >> 8; } elseif ($i + 1 < $srcLen) { /** @var int $c1 */ $c1 = static::$method($chunk[2]); $dest .= \pack( 'C', (($c0 << 3) | ($c1 >> 2) ) & 0xff ); $err |= ($c0 | $c1) >> 8; } else { $dest .= \pack( 'C', (($c0 << 3) ) & 0xff ); $err |= ($c0) >> 8; } } /** @var bool $check */ $check = ($err === 0); if (!$check) { throw new \RangeException( 'Base32::doDecode() only expects characters in the correct base32 alphabet' ); } return $dest; } /** * Base32 Encoding * * @param string $src * @param bool $upper * @param bool $pad * @return string * @throws \TypeError */ protected static function doEncode(string $src, bool $upper = false, $pad = true): string { // We do this to reduce code duplication: $method = $upper ? 'encode5BitsUpper' : 'encode5Bits'; $dest = ''; $srcLen = Binary::safeStrlen($src); // Main loop (no padding): for ($i = 0; $i + 5 <= $srcLen; $i += 5) { /** @var array $chunk */ $chunk = \unpack('C*', Binary::safeSubstr($src, $i, 5)); $b0 = $chunk[1]; $b1 = $chunk[2]; $b2 = $chunk[3]; $b3 = $chunk[4]; $b4 = $chunk[5]; $dest .= static::$method( ($b0 >> 3) & 31) . static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . static::$method((($b1 >> 1) ) & 31) . static::$method((($b1 << 4) | ($b2 >> 4)) & 31) . static::$method((($b2 << 1) | ($b3 >> 7)) & 31) . static::$method((($b3 >> 2) ) & 31) . static::$method((($b3 << 3) | ($b4 >> 5)) & 31) . static::$method( $b4 & 31); } // The last chunk, which may have padding: if ($i < $srcLen) { /** @var array $chunk */ $chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i)); $b0 = $chunk[1]; if ($i + 3 < $srcLen) { $b1 = $chunk[2]; $b2 = $chunk[3]; $b3 = $chunk[4]; $dest .= static::$method( ($b0 >> 3) & 31) . static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . static::$method((($b1 >> 1) ) & 31) . static::$method((($b1 << 4) | ($b2 >> 4)) & 31) . static::$method((($b2 << 1) | ($b3 >> 7)) & 31) . static::$method((($b3 >> 2) ) & 31) . static::$method((($b3 << 3) ) & 31); if ($pad) { $dest .= '='; } } elseif ($i + 2 < $srcLen) { $b1 = $chunk[2]; $b2 = $chunk[3]; $dest .= static::$method( ($b0 >> 3) & 31) . static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . static::$method((($b1 >> 1) ) & 31) . static::$method((($b1 << 4) | ($b2 >> 4)) & 31) . static::$method((($b2 << 1) ) & 31); if ($pad) { $dest .= '==='; } } elseif ($i + 1 < $srcLen) { $b1 = $chunk[2]; $dest .= static::$method( ($b0 >> 3) & 31) . static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . static::$method((($b1 >> 1) ) & 31) . static::$method((($b1 << 4) ) & 31); if ($pad) { $dest .= '===='; } } else { $dest .= static::$method( ($b0 >> 3) & 31) . static::$method( ($b0 << 2) & 31); if ($pad) { $dest .= '======'; } } } return $dest; } } constant_time_encoding-2.3.0/src/Base32Hex.php000066400000000000000000000065311356061637500212360ustar00rootroot00000000000000 0x30 && $src < 0x3a) ret += $src - 0x2e + 1; // -47 $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src - 47); // if ($src > 0x60 && $src < 0x77) ret += $src - 0x61 + 10 + 1; // -86 $ret += (((0x60 - $src) & ($src - 0x77)) >> 8) & ($src - 86); return $ret; } /** * Uses bitwise operators instead of table-lookups to turn 5-bit integers * into 8-bit integers. * * @param int $src * @return int */ protected static function decode5BitsUpper(int $src): int { $ret = -1; // if ($src > 0x30 && $src < 0x3a) ret += $src - 0x2e + 1; // -47 $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src - 47); // if ($src > 0x40 && $src < 0x57) ret += $src - 0x41 + 10 + 1; // -54 $ret += (((0x40 - $src) & ($src - 0x57)) >> 8) & ($src - 54); return $ret; } /** * Uses bitwise operators instead of table-lookups to turn 8-bit integers * into 5-bit integers. * * @param int $src * @return string */ protected static function encode5Bits(int $src): string { $src += 0x30; // if ($src > 0x39) $src += 0x61 - 0x3a; // 39 $src += ((0x39 - $src) >> 8) & 39; return \pack('C', $src); } /** * Uses bitwise operators instead of table-lookups to turn 8-bit integers * into 5-bit integers. * * Uppercase variant. * * @param int $src * @return string */ protected static function encode5BitsUpper(int $src): string { $src += 0x30; // if ($src > 0x39) $src += 0x41 - 0x3a; // 7 $src += ((0x39 - $src) >> 8) & 7; return \pack('C', $src); } }constant_time_encoding-2.3.0/src/Base64.php000066400000000000000000000212111356061637500205660ustar00rootroot00000000000000 $chunk */ $chunk = \unpack('C*', Binary::safeSubstr($src, $i, 3)); $b0 = $chunk[1]; $b1 = $chunk[2]; $b2 = $chunk[3]; $dest .= static::encode6Bits( $b0 >> 2 ) . static::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) . static::encode6Bits((($b1 << 2) | ($b2 >> 6)) & 63) . static::encode6Bits( $b2 & 63); } // The last chunk, which may have padding: if ($i < $srcLen) { /** @var array $chunk */ $chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i)); $b0 = $chunk[1]; if ($i + 1 < $srcLen) { $b1 = $chunk[2]; $dest .= static::encode6Bits($b0 >> 2) . static::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) . static::encode6Bits(($b1 << 2) & 63); if ($pad) { $dest .= '='; } } else { $dest .= static::encode6Bits( $b0 >> 2) . static::encode6Bits(($b0 << 4) & 63); if ($pad) { $dest .= '=='; } } } return $dest; } /** * decode from base64 into binary * * Base64 character set "./[A-Z][a-z][0-9]" * * @param string $src * @param bool $strictPadding * @return string * @throws \RangeException * @throws \TypeError * @psalm-suppress RedundantCondition */ public static function decode(string $src, bool $strictPadding = false): string { // Remove padding $srcLen = Binary::safeStrlen($src); if ($srcLen === 0) { return ''; } if ($strictPadding) { if (($srcLen & 3) === 0) { if ($src[$srcLen - 1] === '=') { $srcLen--; if ($src[$srcLen - 1] === '=') { $srcLen--; } } } if (($srcLen & 3) === 1) { throw new \RangeException( 'Incorrect padding' ); } if ($src[$srcLen - 1] === '=') { throw new \RangeException( 'Incorrect padding' ); } } else { $src = \rtrim($src, '='); $srcLen = Binary::safeStrlen($src); } $err = 0; $dest = ''; // Main loop (no padding): for ($i = 0; $i + 4 <= $srcLen; $i += 4) { /** @var array $chunk */ $chunk = \unpack('C*', Binary::safeSubstr($src, $i, 4)); $c0 = static::decode6Bits($chunk[1]); $c1 = static::decode6Bits($chunk[2]); $c2 = static::decode6Bits($chunk[3]); $c3 = static::decode6Bits($chunk[4]); $dest .= \pack( 'CCC', ((($c0 << 2) | ($c1 >> 4)) & 0xff), ((($c1 << 4) | ($c2 >> 2)) & 0xff), ((($c2 << 6) | $c3 ) & 0xff) ); $err |= ($c0 | $c1 | $c2 | $c3) >> 8; } // The last chunk, which may have padding: if ($i < $srcLen) { /** @var array $chunk */ $chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i)); $c0 = static::decode6Bits($chunk[1]); if ($i + 2 < $srcLen) { $c1 = static::decode6Bits($chunk[2]); $c2 = static::decode6Bits($chunk[3]); $dest .= \pack( 'CC', ((($c0 << 2) | ($c1 >> 4)) & 0xff), ((($c1 << 4) | ($c2 >> 2)) & 0xff) ); $err |= ($c0 | $c1 | $c2) >> 8; } elseif ($i + 1 < $srcLen) { $c1 = static::decode6Bits($chunk[2]); $dest .= \pack( 'C', ((($c0 << 2) | ($c1 >> 4)) & 0xff) ); $err |= ($c0 | $c1) >> 8; } elseif ($i < $srcLen && $strictPadding) { $err |= 1; } } /** @var bool $check */ $check = ($err === 0); if (!$check) { throw new \RangeException( 'Base64::decode() only expects characters in the correct base64 alphabet' ); } return $dest; } /** * Uses bitwise operators instead of table-lookups to turn 6-bit integers * into 8-bit integers. * * Base64 character set: * [A-Z] [a-z] [0-9] + / * 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2b, 0x2f * * @param int $src * @return int */ protected static function decode6Bits(int $src): int { $ret = -1; // if ($src > 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64 $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64); // if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70 $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 70); // if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5 $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 5); // if ($src == 0x2b) $ret += 62 + 1; $ret += (((0x2a - $src) & ($src - 0x2c)) >> 8) & 63; // if ($src == 0x2f) ret += 63 + 1; $ret += (((0x2e - $src) & ($src - 0x30)) >> 8) & 64; return $ret; } /** * Uses bitwise operators instead of table-lookups to turn 8-bit integers * into 6-bit integers. * * @param int $src * @return string */ protected static function encode6Bits(int $src): string { $diff = 0x41; // if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6 $diff += ((25 - $src) >> 8) & 6; // if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75 $diff -= ((51 - $src) >> 8) & 75; // if ($src > 61) $diff += 0x2b - 0x30 - 10; // -15 $diff -= ((61 - $src) >> 8) & 15; // if ($src > 62) $diff += 0x2f - 0x2b - 1; // 3 $diff += ((62 - $src) >> 8) & 3; return \pack('C', $src + $diff); } } constant_time_encoding-2.3.0/src/Base64DotSlash.php000066400000000000000000000057371356061637500222470ustar00rootroot00000000000000 0x2d && $src < 0x30) ret += $src - 0x2e + 1; // -45 $ret += (((0x2d - $src) & ($src - 0x30)) >> 8) & ($src - 45); // if ($src > 0x40 && $src < 0x5b) ret += $src - 0x41 + 2 + 1; // -62 $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 62); // if ($src > 0x60 && $src < 0x7b) ret += $src - 0x61 + 28 + 1; // -68 $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 68); // if ($src > 0x2f && $src < 0x3a) ret += $src - 0x30 + 54 + 1; // 7 $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 7); return $ret; } /** * Uses bitwise operators instead of table-lookups to turn 8-bit integers * into 6-bit integers. * * @param int $src * @return string */ protected static function encode6Bits(int $src): string { $src += 0x2e; // if ($src > 0x2f) $src += 0x41 - 0x30; // 17 $src += ((0x2f - $src) >> 8) & 17; // if ($src > 0x5a) $src += 0x61 - 0x5b; // 6 $src += ((0x5a - $src) >> 8) & 6; // if ($src > 0x7a) $src += 0x30 - 0x7b; // -75 $src -= ((0x7a - $src) >> 8) & 75; return \pack('C', $src); } } constant_time_encoding-2.3.0/src/Base64DotSlashOrdered.php000066400000000000000000000053401356061637500235420ustar00rootroot00000000000000 0x2d && $src < 0x3a) ret += $src - 0x2e + 1; // -45 $ret += (((0x2d - $src) & ($src - 0x3a)) >> 8) & ($src - 45); // if ($src > 0x40 && $src < 0x5b) ret += $src - 0x41 + 12 + 1; // -52 $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 52); // if ($src > 0x60 && $src < 0x7b) ret += $src - 0x61 + 38 + 1; // -58 $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 58); return $ret; } /** * Uses bitwise operators instead of table-lookups to turn 8-bit integers * into 6-bit integers. * * @param int $src * @return string */ protected static function encode6Bits(int $src): string { $src += 0x2e; // if ($src > 0x39) $src += 0x41 - 0x3a; // 7 $src += ((0x39 - $src) >> 8) & 7; // if ($src > 0x5a) $src += 0x61 - 0x5b; // 6 $src += ((0x5a - $src) >> 8) & 6; return \pack('C', $src); } } constant_time_encoding-2.3.0/src/Base64UrlSafe.php000066400000000000000000000062341356061637500220600ustar00rootroot00000000000000 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64 $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64); // if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70 $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 70); // if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5 $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 5); // if ($src == 0x2c) $ret += 62 + 1; $ret += (((0x2c - $src) & ($src - 0x2e)) >> 8) & 63; // if ($src == 0x5f) ret += 63 + 1; $ret += (((0x5e - $src) & ($src - 0x60)) >> 8) & 64; return $ret; } /** * Uses bitwise operators instead of table-lookups to turn 8-bit integers * into 6-bit integers. * * @param int $src * @return string */ protected static function encode6Bits(int $src): string { $diff = 0x41; // if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6 $diff += ((25 - $src) >> 8) & 6; // if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75 $diff -= ((51 - $src) >> 8) & 75; // if ($src > 61) $diff += 0x2d - 0x30 - 10; // -13 $diff -= ((61 - $src) >> 8) & 13; // if ($src > 62) $diff += 0x5f - 0x2b - 1; // 3 $diff += ((62 - $src) >> 8) & 49; return \pack('C', $src + $diff); } } constant_time_encoding-2.3.0/src/Binary.php000066400000000000000000000050561356061637500207770ustar00rootroot00000000000000 $chunk */ $chunk = \unpack('C', Binary::safeSubstr($binString, $i, 1)); /** @var int $c */ $c = $chunk[1] & 0xf; /** @var int $b */ $b = $chunk[1] >> 4; $hex .= pack( 'CC', (87 + $b + ((($b - 10) >> 8) & ~38)), (87 + $c + ((($c - 10) >> 8) & ~38)) ); } return $hex; } /** * Convert a binary string into a hexadecimal string without cache-timing * leaks, returning uppercase letters (as per RFC 4648) * * @param string $binString (raw binary) * @return string * @throws \TypeError */ public static function encodeUpper(string $binString): string { /** @var string $hex */ $hex = ''; /** @var int $len */ $len = Binary::safeStrlen($binString); for ($i = 0; $i < $len; ++$i) { /** @var array $chunk */ $chunk = \unpack('C', Binary::safeSubstr($binString, $i, 2)); /** @var int $c */ $c = $chunk[1] & 0xf; /** @var int $b */ $b = $chunk[1] >> 4; $hex .= pack( 'CC', (55 + $b + ((($b - 10) >> 8) & ~6)), (55 + $c + ((($c - 10) >> 8) & ~6)) ); } return $hex; } /** * Convert a hexadecimal string into a binary string without cache-timing * leaks * * @param string $hexString * @param bool $strictPadding * @return string (raw binary) * @throws \RangeException */ public static function decode(string $hexString, bool $strictPadding = false): string { /** @var int $hex_pos */ $hex_pos = 0; /** @var string $bin */ $bin = ''; /** @var int $c_acc */ $c_acc = 0; /** @var int $hex_len */ $hex_len = Binary::safeStrlen($hexString); /** @var int $state */ $state = 0; if (($hex_len & 1) !== 0) { if ($strictPadding) { throw new \RangeException( 'Expected an even number of hexadecimal characters' ); } else { $hexString = '0' . $hexString; ++$hex_len; } } /** @var array $chunk */ $chunk = \unpack('C*', $hexString); while ($hex_pos < $hex_len) { ++$hex_pos; /** @var int $c */ $c = $chunk[$hex_pos]; /** @var int $c_num */ $c_num = $c ^ 48; /** @var int $c_num0 */ $c_num0 = ($c_num - 10) >> 8; /** @var int $c_alpha */ $c_alpha = ($c & ~32) - 55; /** @var int $c_alpha0 */ $c_alpha0 = (($c_alpha - 10) ^ ($c_alpha - 16)) >> 8; if (($c_num0 | $c_alpha0) === 0) { throw new \RangeException( 'hexEncode() only expects hexadecimal characters' ); } /** @var int $c_val */ $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; } return $bin; } } constant_time_encoding-2.3.0/src/RFC4648.php000066400000000000000000000102161356061637500205050ustar00rootroot00000000000000 "Zm9v" * * @param string $str * @return string * @throws \TypeError */ public static function base64Encode(string $str): string { return Base64::encode($str); } /** * RFC 4648 Base64 decoding * * "Zm9v" -> "foo" * * @param string $str * @return string * @throws \TypeError */ public static function base64Decode(string $str): string { return Base64::decode($str, true); } /** * RFC 4648 Base64 (URL Safe) encoding * * "foo" -> "Zm9v" * * @param string $str * @return string * @throws \TypeError */ public static function base64UrlSafeEncode(string $str): string { return Base64UrlSafe::encode($str); } /** * RFC 4648 Base64 (URL Safe) decoding * * "Zm9v" -> "foo" * * @param string $str * @return string * @throws \TypeError */ public static function base64UrlSafeDecode(string $str): string { return Base64UrlSafe::decode($str, true); } /** * RFC 4648 Base32 encoding * * "foo" -> "MZXW6===" * * @param string $str * @return string * @throws \TypeError */ public static function base32Encode(string $str): string { return Base32::encodeUpper($str); } /** * RFC 4648 Base32 encoding * * "MZXW6===" -> "foo" * * @param string $str * @return string * @throws \TypeError */ public static function base32Decode(string $str): string { return Base32::decodeUpper($str, true); } /** * RFC 4648 Base32-Hex encoding * * "foo" -> "CPNMU===" * * @param string $str * @return string * @throws \TypeError */ public static function base32HexEncode(string $str): string { return Base32::encodeUpper($str); } /** * RFC 4648 Base32-Hex decoding * * "CPNMU===" -> "foo" * * @param string $str * @return string * @throws \TypeError */ public static function base32HexDecode(string $str): string { return Base32::decodeUpper($str, true); } /** * RFC 4648 Base16 decoding * * "foo" -> "666F6F" * * @param string $str * @return string * @throws \TypeError */ public static function base16Encode(string $str): string { return Hex::encodeUpper($str); } /** * RFC 4648 Base16 decoding * * "666F6F" -> "foo" * * @param string $str * @return string */ public static function base16Decode(string $str): string { return Hex::decode($str, true); } }constant_time_encoding-2.3.0/tests/000077500000000000000000000000001356061637500174075ustar00rootroot00000000000000constant_time_encoding-2.3.0/tests/Base32HexTest.php000066400000000000000000000027101356061637500224440ustar00rootroot00000000000000assertSame( $random, Base32Hex::decode($enc) ); $unpadded = \rtrim($enc, '='); $this->assertSame( $unpadded, Base32Hex::encodeUnpadded($random) ); $this->assertSame( $random, Base32Hex::decode($unpadded) ); $enc = Base32Hex::encodeUpper($random); $this->assertSame( $random, Base32Hex::decodeUpper($enc) ); $unpadded = \rtrim($enc, '='); $this->assertSame( $unpadded, Base32Hex::encodeUpperUnpadded($random) ); $this->assertSame( $random, Base32Hex::decodeUpper($unpadded) ); } } } } constant_time_encoding-2.3.0/tests/Base32Test.php000066400000000000000000000026371356061637500220070ustar00rootroot00000000000000assertSame( $random, Base32::decode($enc) ); $unpadded = \rtrim($enc, '='); $this->assertSame( $unpadded, Base32::encodeUnpadded($random) ); $this->assertSame( $random, Base32::decode($unpadded) ); $enc = Base32::encodeUpper($random); $this->assertSame( $random, Base32::decodeUpper($enc) ); $unpadded = \rtrim($enc, '='); $this->assertSame( $unpadded, Base32::encodeUpperUnpadded($random) ); $this->assertSame( $random, Base32::decodeUpper($unpadded) ); } } } } constant_time_encoding-2.3.0/tests/Base64DotSlashOrderedTest.php000066400000000000000000000017141356061637500247560ustar00rootroot00000000000000assertSame( $random, Base64DotSlashOrdered::decode($enc) ); $unpadded = \rtrim($enc, '='); $this->assertSame( $random, Base64DotSlashOrdered::decode($unpadded) ); $this->assertSame( $random, Base64DotSlashOrdered::decode($unpadded) ); } } } } constant_time_encoding-2.3.0/tests/Base64DotSlashTest.php000066400000000000000000000016241356061637500234510ustar00rootroot00000000000000assertSame( $random, Base64DotSlash::decode($enc) ); $unpadded = \rtrim($enc, '='); $this->assertSame( $random, Base64DotSlash::decode($unpadded) ); $this->assertSame( $random, Base64DotSlash::decode($unpadded) ); } } } } constant_time_encoding-2.3.0/tests/Base64Test.php000066400000000000000000000072631356061637500220140ustar00rootroot00000000000000assertSame( $random, Base64::decode($enc) ); $this->assertSame( \base64_encode($random), $enc ); $unpadded = \rtrim($enc, '='); $this->assertSame( $random, Base64::decode($unpadded) ); $this->assertSame( $random, Base64::decode($unpadded) ); } } $str = 'MIIFzzCCBLegAwIBAgIDAfdlMA0GCSqGSIb3DQEBBQUAMHMxCzAJBgNVBAYTAlBM' . 'MSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMSQwIgYDVQQ' . 'DDBtDT1BFIFNaQUZJUiAtIEt3YWxpZmlrb3dhbnkxFDASBgNVBAUTC05yIHdwaXN1Oi' . 'A2MB4XDTExMTEwOTA2MDAwMFoXDTEzMTEwOTA2MDAwMFowgdkxCzAJBgNVBAYTAlBMM' . 'RwwGgYDVQQKDBNVcnrEhWQgTWlhc3RhIEdkeW5pMRswGQYDVQQFExJQRVNFTDogNjEw' . 'NjA2MDMxMTgxGTAXBgNVBAMMEEplcnp5IFByemV3b3Jza2kxTzBNBgNVBBAwRgwiQWw' . 'uIE1hcnN6YcWCa2EgUGnFgnN1ZHNraWVnbyA1Mi81NAwNODEtMzgyIEdkeW5pYQwGUG' . '9sc2thDAlwb21vcnNraWUxDjAMBgNVBCoMBUplcnp5MRMwEQYDVQQEDApQcnpld29yc' . '2tpMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCMm5vjGqHPthJCMqKpqssSISRo' . 's0PYDTcEQzyyurfX67EJWKtZj6HNwuDMEGJ02iBNZfjUl7r8dIi28bSKhNlsfycXZKY' . 'RcIjp0+r5RqtR2auo9GQ6veKb61DEAGIqaR+uLLcJVTHCu0w9oXLGbRlGth5eNoj03C' . 'xXVAH2IfhbNwIDAQABo4IChzCCAoMwDAYDVR0TAQH/BAIwADCCAUgGA1UdIAEB/wSCA' . 'TwwggE4MIIBNAYJKoRoAYb3IwEBMIIBJTCB3QYIKwYBBQUHAgIwgdAMgc1EZWtsYXJh' . 'Y2phIHRhIGplc3Qgb8Wbd2lhZGN6ZW5pZW0gd3lkYXdjeSwgxbxlIHRlbiBjZXJ0eWZ' . 'pa2F0IHpvc3RhxYIgd3lkYW55IGpha28gY2VydHlmaWthdCBrd2FsaWZpa293YW55IH' . 'pnb2RuaWUgeiB3eW1hZ2FuaWFtaSB1c3Rhd3kgbyBwb2RwaXNpZSBlbGVrdHJvbmlje' . 'm55bSBvcmF6IHRvd2FyenlzesSFY3ltaSBqZWogcm96cG9yesSFZHplbmlhbWkuMEMG' . 'CCsGAQUFBwIBFjdodHRwOi8vd3d3Lmtpci5jb20ucGwvY2VydHlmaWthY2phX2tsdWN' . '6eS9wb2xpdHlrYS5odG1sMAkGA1UdCQQCMAAwIQYDVR0RBBowGIEWai5wcnpld29yc2' . 'tpQGdkeW5pYS5wbDAOBgNVHQ8BAf8EBAMCBkAwgZ4GA1UdIwSBljCBk4AU3TGldJXip' . 'N4oGS3ZYmnBDMFs8gKhd6R1MHMxCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dh' . 'IEl6YmEgUm96bGljemVuaW93YSBTLkEuMSQwIgYDVQQDDBtDT1BFIFNaQUZJUiAtIEt' . '3YWxpZmlrb3dhbnkxFDASBgNVBAUTC05yIHdwaXN1OiA2ggJb9jBIBgNVHR8EQTA/MD' . '2gO6A5hjdodHRwOi8vd3d3Lmtpci5jb20ucGwvY2VydHlmaWthY2phX2tsdWN6eS9DU' . 'kxfT1pLMzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQBYPIqnAreyeql7/opJjcar/qWZ' . 'y9ruhB2q0lZFsJOhwgMnbQXzp/4vv93YJqcHGAXdHP6EO8FQX47mjo2ZKQmi+cIHJHL' . 'ONdX/3Im+M17V0iNAh7Z1lOSfTRT+iiwe/F8phcEaD5q2RmvYusR7zXZq/cLL0If0hX' . 'oPZ/EHQxjN8pxzxiUx6bJAgturnIMEfRNesxwghdr1dkUjOhGLf3kHVzgM6j3VAM7oF' . 'mMUb5y5s96Bzl10DodWitjOEH0vvnIcsppSxH1C1dCAi0o9f/1y2XuLNhBNHMAyTqpY' . 'PX8Yvav1c+Z50OMaSXHAnTa20zv8UtiHbaAhwlifCelUMj93S'; try { Base64::decode($str, true); $this->fail('Strict padding not enforced'); } catch (\Exception $ex) { $this->assertSame( Base64::decode($str), \base64_decode($str) ); } } } constant_time_encoding-2.3.0/tests/Base64UrlSafeTest.php000066400000000000000000000030151356061637500232650ustar00rootroot00000000000000assertSame( $random, Base64UrlSafe::decode($enc) ); $this->assertSame( \strtr(\base64_encode($random), '+/', '-_'), $enc ); $unpadded = \rtrim($enc, '='); $this->assertSame( $unpadded, Base64UrlSafe::encodeUnpadded($random) ); $this->assertSame( $random, Base64UrlSafe::decode($unpadded) ); } } $random = \random_bytes(1 << 20); $enc = Base64UrlSafe::encode($random); $this->assertTrue(Binary::safeStrlen($enc) > 65536); $this->assertSame( $random, Base64UrlSafe::decode($enc) ); $this->assertSame( \strtr(\base64_encode($random), '+/', '-_'), $enc ); } } constant_time_encoding-2.3.0/tests/EncodingTest.php000066400000000000000000000222101356061637500225030ustar00rootroot00000000000000assertSame( Encoding::base32Encode("\x00"), 'aa======' ); $this->assertSame( Encoding::base32Encode("\x00\x00"), 'aaaa====' ); $this->assertSame( Encoding::base32Encode("\x00\x00\x00"), 'aaaaa===' ); $this->assertSame( Encoding::base32Encode("\x00\x00\x00\x00"), 'aaaaaaa=' ); $this->assertSame( Encoding::base32Encode("\x00\x00\x00\x00\x00"), 'aaaaaaaa' ); $this->assertSame( Encoding::base32Encode("\x00\x00\x0F\xFF\xFF"), 'aaaa7777' ); $this->assertSame( Encoding::base32Encode("\xFF\xFF\xF0\x00\x00"), '7777aaaa' ); $this->assertSame( Encoding::base32Encode("\xce\x73\x9c\xe7\x39"), 'zzzzzzzz' ); $this->assertSame( Encoding::base32Encode("\xd6\xb5\xad\x6b\x5a"), '22222222' ); $this->assertSame( Base32::encodeUpper("\x00"), 'AA======' ); $this->assertSame( Base32::encodeUpper("\x00\x00"), 'AAAA====' ); $this->assertSame( Base32::encodeUpper("\x00\x00\x00"), 'AAAAA===' ); $this->assertSame( Base32::encodeUpper("\x00\x00\x00\x00"), 'AAAAAAA=' ); $this->assertSame( Base32::encodeUpper("\x00\x00\x00\x00\x00"), 'AAAAAAAA' ); $this->assertSame( Base32::encodeUpper("\x00\x00\x0F\xFF\xFF"), 'AAAA7777' ); $this->assertSame( Base32::encodeUpper("\xFF\xFF\xF0\x00\x00"), '7777AAAA' ); $this->assertSame( Base32::encodeUpper("\xce\x73\x9c\xe7\x39"), 'ZZZZZZZZ' ); $this->assertSame( Base32::encodeUpper("\xd6\xb5\xad\x6b\x5a"), '22222222' ); } public function testBase32Hex() { $this->assertSame( Base32Hex::encode("\x00"), '00======' ); $this->assertSame( Base32Hex::encode("\x00\x00"), '0000====' ); $this->assertSame( Base32Hex::encode("\x00\x00\x00"), '00000===' ); $this->assertSame( Base32Hex::encode("\x00\x00\x00\x00"), '0000000=' ); $this->assertSame( Base32Hex::encode("\x00\x00\x00\x00\x00"), '00000000' ); $this->assertSame( Base32Hex::encode("\x00\x00\x0F\xFF\xFF"), '0000vvvv' ); $this->assertSame( Base32Hex::encode("\xFF\xFF\xF0\x00\x00"), 'vvvv0000' ); } /** * Based on test vectors from RFC 4648 */ public function testBase32Decode() { $this->assertSame( "\x00\x00\x00\x00\x00\x00", Encoding::base32Decode('aaaaaaaaaa======') ); $this->assertSame( "\x00\x00\x00\x00\x00\x00\x00", Encoding::base32Decode('aaaaaaaaaaaa====') ); $this->assertSame( "\x00\x00\x00\x00\x00\x00\x00\x00", Encoding::base32Decode('aaaaaaaaaaaaa===') ); $this->assertSame( "\x00\x00\x00\x00\x00\x00\x00\x00\x00", Encoding::base32Decode('aaaaaaaaaaaaaaa=') ); $this->assertSame( "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", Encoding::base32Decode('aaaaaaaaaaaaaaaa') ); $this->assertSame( "\x00", Encoding::base32Decode('aa======') ); $this->assertSame( "\x00\x00", Encoding::base32Decode('aaaa====') ); $this->assertSame( "\x00\x00\x00", Encoding::base32Decode('aaaaa===') ); $this->assertSame( "\x00\x00\x00\x00", Encoding::base32Decode('aaaaaaa=') ); $this->assertSame( "\x00\x00\x00\x00\x00", Encoding::base32Decode('aaaaaaaa') ); $this->assertSame( "\x00\x00\x0F\xFF\xFF", Encoding::base32Decode('aaaa7777') ); $this->assertSame( "\xFF\xFF\xF0\x00\x00", Encoding::base32Decode('7777aaaa') ); $this->assertSame( "\xce\x73\x9c\xe7\x39", Encoding::base32Decode('zzzzzzzz') ); $this->assertSame( "\xd6\xb5\xad\x6b\x5a", Encoding::base32Decode('22222222') ); $this->assertSame( 'foobar', Encoding::base32Decode('mzxw6ytboi======') ); $rand = random_bytes(9); $enc = Encoding::base32Encode($rand); $this->assertSame( Encoding::base32Encode($rand), Encoding::base32Encode(Encoding::base32Decode($enc)) ); $this->assertSame( $rand, Encoding::base32Decode($enc) ); } /** * @covers Encoding::hexDecode() * @covers Encoding::hexEncode() * @covers Encoding::base32Decode() * @covers Encoding::base32Encode() * @covers Encoding::base64Decode() * @covers Encoding::base64Encode() * @covers Encoding::base64DotSlashDecode() * @covers Encoding::base64DotSlashEncode() * @covers Encoding::base64DotSlashOrderedDecode() * @covers Encoding::base64DotSlashOrderedEncode() */ public function testBasicEncoding() { // Re-run the test at least 3 times for each length for ($j = 0; $j < 3; ++$j) { for ($i = 1; $i < 84; ++$i) { $rand = random_bytes($i); $enc = Encoding::hexEncode($rand); $this->assertSame( \bin2hex($rand), $enc, "Hex Encoding - Length: " . $i ); $this->assertSame( $rand, Encoding::hexDecode($enc), "Hex Encoding - Length: " . $i ); // Uppercase variant: $enc = Hex::encodeUpper($rand); $this->assertSame( \strtoupper(\bin2hex($rand)), $enc, "Hex Encoding - Length: " . $i ); $this->assertSame( $rand, Hex::decode($enc), "HexUpper Encoding - Length: " . $i ); $enc = Encoding::base32Encode($rand); $this->assertSame( $rand, Encoding::base32Decode($enc), "Base32 Encoding - Length: " . $i ); $enc = Encoding::base32EncodeUpper($rand); $this->assertSame( $rand, Encoding::base32DecodeUpper($enc), "Base32Upper Encoding - Length: " . $i ); $enc = Encoding::base32HexEncode($rand); $this->assertSame( bin2hex($rand), bin2hex(Encoding::base32HexDecode($enc)), "Base32Hex Encoding - Length: " . $i ); $enc = Encoding::base32HexEncodeUpper($rand); $this->assertSame( bin2hex($rand), bin2hex(Encoding::base32HexDecodeUpper($enc)), "Base32HexUpper Encoding - Length: " . $i ); $enc = Encoding::base64Encode($rand); $this->assertSame( $rand, Encoding::base64Decode($enc), "Base64 Encoding - Length: " . $i ); $enc = Encoding::base64EncodeDotSlash($rand); $this->assertSame( $rand, Encoding::base64DecodeDotSlash($enc), "Base64 DotSlash Encoding - Length: " . $i ); $enc = Encoding::base64EncodeDotSlashOrdered($rand); $this->assertSame( $rand, Encoding::base64DecodeDotSlashOrdered($enc), "Base64 Ordered DotSlash Encoding - Length: " . $i ); $enc = Base64UrlSafe::encode($rand); $this->assertSame( \strtr(\base64_encode($rand), '+/', '-_'), $enc ); $this->assertSame( $rand, Base64UrlSafe::decode($enc) ); } } } }constant_time_encoding-2.3.0/tests/HexTest.php000066400000000000000000000017271356061637500215130ustar00rootroot00000000000000assertSame( $random, Hex::decode($enc) ); $this->assertSame( \bin2hex($random), $enc ); $enc = Hex::encodeUpper($random); $this->assertSame( $random, Hex::decode($enc) ); $this->assertSame( \strtoupper(\bin2hex($random)), $enc ); } } } } constant_time_encoding-2.3.0/tests/RFC4648Test.php000066400000000000000000000072301356061637500217220ustar00rootroot00000000000000assertSame(Base64::encode(''), ''); $this->assertSame(Base64::encode('f'), 'Zg=='); $this->assertSame(Base64::encode('fo'), 'Zm8='); $this->assertSame(Base64::encode('foo'), 'Zm9v'); $this->assertSame(Base64::encode('foob'), 'Zm9vYg=='); $this->assertSame(Base64::encode('fooba'), 'Zm9vYmE='); $this->assertSame(Base64::encode('foobar'), 'Zm9vYmFy'); } public function testVectorBase32() { $this->assertSame(Base32::encode(''), ''); $this->assertSame(Base32::encode('f'), 'my======'); $this->assertSame(Base32::encode('fo'), 'mzxq===='); $this->assertSame(Base32::encode('foo'), 'mzxw6==='); $this->assertSame(Base32::encode('foob'), 'mzxw6yq='); $this->assertSame(Base32::encode('fooba'), 'mzxw6ytb'); $this->assertSame(Base32::encode('foobar'), 'mzxw6ytboi======'); $this->assertSame(Base32::encodeUpper(''), ''); $this->assertSame(Base32::encodeUpper('f'), 'MY======'); $this->assertSame(Base32::encodeUpper('fo'), 'MZXQ===='); $this->assertSame(Base32::encodeUpper('foo'), 'MZXW6==='); $this->assertSame(Base32::encodeUpper('foob'), 'MZXW6YQ='); $this->assertSame(Base32::encodeUpper('fooba'), 'MZXW6YTB'); $this->assertSame(Base32::encodeUpper('foobar'), 'MZXW6YTBOI======'); } public function testVectorBase32Hex() { $this->assertSame(Base32Hex::encode(''), ''); $this->assertSame(Base32Hex::encode('f'), 'co======'); $this->assertSame(Base32Hex::encode('fo'), 'cpng===='); $this->assertSame(Base32Hex::encode('foo'), 'cpnmu==='); $this->assertSame(Base32Hex::encode('foob'), 'cpnmuog='); $this->assertSame(Base32Hex::encode('fooba'), 'cpnmuoj1'); $this->assertSame(Base32Hex::encode('foobar'), 'cpnmuoj1e8======'); $this->assertSame(Base32Hex::encodeUpper(''), ''); $this->assertSame(Base32Hex::encodeUpper('f'), 'CO======'); $this->assertSame(Base32Hex::encodeUpper('fo'), 'CPNG===='); $this->assertSame(Base32Hex::encodeUpper('foo'), 'CPNMU==='); $this->assertSame(Base32Hex::encodeUpper('foob'), 'CPNMUOG='); $this->assertSame(Base32Hex::encodeUpper('fooba'), 'CPNMUOJ1'); $this->assertSame(Base32Hex::encodeUpper('foobar'), 'CPNMUOJ1E8======'); } public function testVectorBase16() { $this->assertSame(Hex::encode(''), ''); $this->assertSame(Hex::encode('f'), '66'); $this->assertSame(Hex::encode('fo'), '666f'); $this->assertSame(Hex::encode('foo'), '666f6f'); $this->assertSame(Hex::encode('foob'), '666f6f62'); $this->assertSame(Hex::encode('fooba'), '666f6f6261'); $this->assertSame(Hex::encode('foobar'), '666f6f626172'); $this->assertSame(Hex::encodeUpper(''), ''); $this->assertSame(Hex::encodeUpper('f'), '66'); $this->assertSame(Hex::encodeUpper('fo'), '666F'); $this->assertSame(Hex::encodeUpper('foo'), '666F6F'); $this->assertSame(Hex::encodeUpper('foob'), '666F6F62'); $this->assertSame(Hex::encodeUpper('fooba'), '666F6F6261'); $this->assertSame(Hex::encodeUpper('foobar'), '666F6F626172'); } }