pax_global_header00006660000000000000000000000064131612221510014504gustar00rootroot0000000000000052 comment=9e7d88e6e4015c2f06a3fa22f06e1d5faa77e6c4 constant_time_encoding-2.2.0/000077500000000000000000000000001316122215100162225ustar00rootroot00000000000000constant_time_encoding-2.2.0/.gitignore000066400000000000000000000000161316122215100202070ustar00rootroot00000000000000.idea/ vendor/constant_time_encoding-2.2.0/.travis.yml000066400000000000000000000003271316122215100203350ustar00rootroot00000000000000language: php sudo: false php: - "7.0" - "7.1" - "7.2" matrix: fast_finish: true install: - composer self-update - composer update script: - vendor/bin/phpunit - vendor/bin/psalm constant_time_encoding-2.2.0/LICENSE.txt000066400000000000000000000045361316122215100200550ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2016 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.2.0/README.md000066400000000000000000000044111316122215100175010ustar00rootroot00000000000000# Constant-Time Encoding [![Build Status](https://travis-ci.org/paragonie/constant_time_encoding.svg?branch=master)](https://travis-ci.org/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==== ``` constant_time_encoding-2.2.0/composer.json000066400000000000000000000022241316122215100207440ustar00rootroot00000000000000{ "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" }, "require-dev": { "phpunit/phpunit": "^6", "vimeo/psalm": "^0.3|^1" }, "autoload": { "psr-4": { "ParagonIE\\ConstantTime\\": "src/" } } } constant_time_encoding-2.2.0/phpunit.xml.dist000066400000000000000000000016141316122215100213770ustar00rootroot00000000000000 tests ./tests ./src constant_time_encoding-2.2.0/psalm.xml000066400000000000000000000003021316122215100200530ustar00rootroot00000000000000 constant_time_encoding-2.2.0/src/000077500000000000000000000000001316122215100170115ustar00rootroot00000000000000constant_time_encoding-2.2.0/src/Base32.php000066400000000000000000000342441316122215100205500ustar00rootroot00000000000000 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 $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 $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 */ 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) { $chunk = \unpack('C*', Binary::safeSubstr($src, $i, 8)); $c0 = static::$method($chunk[1]); $c1 = static::$method($chunk[2]); $c2 = static::$method($chunk[3]); $c3 = static::$method($chunk[4]); $c4 = static::$method($chunk[5]); $c5 = static::$method($chunk[6]); $c6 = static::$method($chunk[7]); $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) { $chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i)); $c0 = static::$method($chunk[1]); if ($i + 6 < $srcLen) { $c1 = static::$method($chunk[2]); $c2 = static::$method($chunk[3]); $c3 = static::$method($chunk[4]); $c4 = static::$method($chunk[5]); $c5 = static::$method($chunk[6]); $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) { $c1 = static::$method($chunk[2]); $c2 = static::$method($chunk[3]); $c3 = static::$method($chunk[4]); $c4 = static::$method($chunk[5]); $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) { $c1 = static::$method($chunk[2]); $c2 = static::$method($chunk[3]); $c3 = static::$method($chunk[4]); $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) { $c1 = static::$method($chunk[2]); $c2 = static::$method($chunk[3]); $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) { $c1 = static::$method($chunk[2]); $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) { $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; } } if ($err !== 0) { throw new \RangeException( 'Base32::doDecode() only expects characters in the correct base32 alphabet' ); } return $dest; } /** * Base32 Decoding * * @param string $src * @param bool $upper * @param bool $pad * @return string */ 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) { $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) { $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.2.0/src/Base32Hex.php000066400000000000000000000065321316122215100212140ustar00rootroot00000000000000 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.2.0/src/Base64.php000066400000000000000000000203771316122215100205570ustar00rootroot00000000000000> 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) { $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 */ 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) { $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) { $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; } } if ($err !== 0) { 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.2.0/src/Base64DotSlash.php000066400000000000000000000057371316122215100222240ustar00rootroot00000000000000 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.2.0/src/Base64DotSlashOrdered.php000066400000000000000000000053401316122215100235170ustar00rootroot00000000000000 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.2.0/src/Base64UrlSafe.php000066400000000000000000000062341316122215100220350ustar00rootroot00000000000000 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.2.0/src/Binary.php000066400000000000000000000050561316122215100207540ustar00rootroot00000000000000> 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 $bin_string (raw binary) * @return string */ public static function encodeUpper(string $bin_string): string { $hex = ''; $len = Binary::safeStrlen($bin_string); for ($i = 0; $i < $len; ++$i) { $chunk = \unpack('C', Binary::safeSubstr($bin_string, $i, 2)); $c = $chunk[1] & 0xf; $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 $hex_string * @param bool $strictPadding * @return string (raw binary) * @throws \RangeException */ public static function decode(string $hexString, bool $strictPadding = false): string { $hex_pos = 0; $bin = ''; $c_acc = 0; $hex_len = Binary::safeStrlen($hexString); $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; } } $chunk = \unpack('C*', $hexString); while ($hex_pos < $hex_len) { ++$hex_pos; $c = $chunk[$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 \RangeException( 'hexEncode() only expects hexadecimal characters' ); } $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.2.0/src/RFC4648.php000066400000000000000000000075361316122215100204750ustar00rootroot00000000000000 "Zm9v" * * @param string $str * @return string */ public function base64Encode(string $str): string { return Base64::encode($str); } /** * RFC 4648 Base64 decoding * * "Zm9v" -> "foo" * * @param string $str * @return string */ public function base64Decode(string $str): string { return Base64::decode($str, true); } /** * RFC 4648 Base64 (URL Safe) encoding * * "foo" -> "Zm9v" * * @param string $str * @return string */ public function base64UrlSafeEncode(string $str): string { return Base64UrlSafe::encode($str); } /** * RFC 4648 Base64 (URL Safe) decoding * * "Zm9v" -> "foo" * * @param string $str * @return string */ public function base64UrlSafeDecode(string $str): string { return Base64UrlSafe::decode($str, true); } /** * RFC 4648 Base32 encoding * * "foo" -> "MZXW6===" * * @param string $str * @return string */ public function base32Encode(string $str): string { return Base32::encodeUpper($str); } /** * RFC 4648 Base32 encoding * * "MZXW6===" -> "foo" * * @param string $str * @return string */ public function base32Decode(string $str): string { return Base32::decodeUpper($str, true); } /** * RFC 4648 Base32-Hex encoding * * "foo" -> "CPNMU===" * * @param string $str * @return string */ public function base32HexEncode(string $str): string { return Base32::encodeUpper($str); } /** * RFC 4648 Base32-Hex decoding * * "CPNMU===" -> "foo" * * @param string $str * @return string */ public function base32HexDecode(string $str): string { return Base32::decodeUpper($str, true); } /** * RFC 4648 Base16 decoding * * "foo" -> "666F6F" * * @param string $str * @return string */ public function base16Encode(string $str): string { return Hex::encodeUpper($str); } /** * RFC 4648 Base16 decoding * * "666F6F" -> "foo" * * @param string $str * @return string */ public function base16Decode(string $str): string { return Hex::decode($str, true); } }constant_time_encoding-2.2.0/tests/000077500000000000000000000000001316122215100173645ustar00rootroot00000000000000constant_time_encoding-2.2.0/tests/Base32HexTest.php000066400000000000000000000027101316122215100224210ustar00rootroot00000000000000assertSame( $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.2.0/tests/Base32Test.php000066400000000000000000000026371316122215100217640ustar00rootroot00000000000000assertSame( $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.2.0/tests/Base64DotSlashOrderedTest.php000066400000000000000000000017141316122215100247330ustar00rootroot00000000000000assertSame( $random, Base64DotSlashOrdered::decode($enc) ); $unpadded = \rtrim($enc, '='); $this->assertSame( $random, Base64DotSlashOrdered::decode($unpadded) ); $this->assertSame( $random, Base64DotSlashOrdered::decode($unpadded) ); } } } } constant_time_encoding-2.2.0/tests/Base64DotSlashTest.php000066400000000000000000000016241316122215100234260ustar00rootroot00000000000000assertSame( $random, Base64DotSlash::decode($enc) ); $unpadded = \rtrim($enc, '='); $this->assertSame( $random, Base64DotSlash::decode($unpadded) ); $this->assertSame( $random, Base64DotSlash::decode($unpadded) ); } } } } constant_time_encoding-2.2.0/tests/Base64Test.php000066400000000000000000000072631316122215100217710ustar00rootroot00000000000000assertSame( $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.2.0/tests/Base64UrlSafeTest.php000066400000000000000000000020441316122215100232430ustar00rootroot00000000000000assertSame( $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) ); } } } } constant_time_encoding-2.2.0/tests/EncodingTest.php000066400000000000000000000222101316122215100224600ustar00rootroot00000000000000assertSame( 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.2.0/tests/HexTest.php000066400000000000000000000017271316122215100214700ustar00rootroot00000000000000assertSame( $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.2.0/tests/RFC4648Test.php000066400000000000000000000072301316122215100216770ustar00rootroot00000000000000assertSame(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'); } }