eaiovnaovbqoebvqoeavibavo constant_time_encoding/psalm.xml000064400000000244150225423570013124 0ustar00 constant_time_encoding/phpunit.xml.dist000064400000001355150225423600014437 0ustar00 ./src ./tests constant_time_encoding/tests/Base64DotSlashOrderedTest.php000064400000001714150225423600017771 0ustar00assertSame( $random, Base64DotSlashOrdered::decode($enc) ); $unpadded = \rtrim($enc, '='); $this->assertSame( $random, Base64DotSlashOrdered::decode($unpadded) ); $this->assertSame( $random, Base64DotSlashOrdered::decode($unpadded) ); } } } } constant_time_encoding/tests/Base32Test.php000064400000002637150225423600015022 0ustar00assertSame( $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/tests/Base32HexTest.php000064400000002710150225423600015457 0ustar00assertSame( $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/tests/HexTest.php000064400000001727150225423600014526 0ustar00assertSame( $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/tests/RFC4648Test.php000064400000007230150225423600014735 0ustar00assertSame(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'); } } constant_time_encoding/tests/Base64Test.php000064400000007263150225423600015027 0ustar00assertSame( $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/tests/EncodingTest.php000064400000022210150225423600015516 0ustar00assertSame( 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/tests/Base64DotSlashTest.php000064400000001624150225423600016464 0ustar00assertSame( $random, Base64DotSlash::decode($enc) ); $unpadded = \rtrim($enc, '='); $this->assertSame( $random, Base64DotSlash::decode($unpadded) ); $this->assertSame( $random, Base64DotSlash::decode($unpadded) ); } } } } constant_time_encoding/tests/Base64UrlSafeTest.php000064400000003015150225423600016300 0ustar00assertSame( $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/README.md000064400000006112150225423600012537 0ustar00# 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/.travis.yml000064400000000551150225423600013372 0ustar00language: php sudo: false matrix: fast_finish: true include: - php: "7.1" - php: "7.2" - php: "7.3" - php: "7.4" - php: "8.0" - php: "nightly" allow_failures: - php: "nightly" - php: "7.4" - php: "8.0" install: - composer self-update - composer update script: - vendor/bin/phpunit - vendor/bin/psalm constant_time_encoding/LICENSE.txt000064400000004545150225423600013113 0ustar00The MIT License (MIT) Copyright (c) 2016 - 2020 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/composer.json000064400000002320150225423600013777 0ustar00{ "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|^8|^9", "vimeo/psalm": "^1|^2|^3|^4" }, "autoload": { "psr-4": { "ParagonIE\\ConstantTime\\": "src/" } } } constant_time_encoding/.gitignore000064400000000016150225423600013245 0ustar00.idea/ vendor/constant_time_encoding/src/Encoding.php000064400000014576150225423600014323 0ustar00 "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/src/Base64.php000064400000021367150225423600013615 0ustar00 $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 $encodedString * @param bool $strictPadding * @return string * @throws \RangeException * @throws \TypeError * @psalm-suppress RedundantCondition */ public static function decode(string $encodedString, bool $strictPadding = false): string { // Remove padding $srcLen = Binary::safeStrlen($encodedString); if ($srcLen === 0) { return ''; } if ($strictPadding) { if (($srcLen & 3) === 0) { if ($encodedString[$srcLen - 1] === '=') { $srcLen--; if ($encodedString[$srcLen - 1] === '=') { $srcLen--; } } } if (($srcLen & 3) === 1) { throw new \RangeException( 'Incorrect padding' ); } if ($encodedString[$srcLen - 1] === '=') { throw new \RangeException( 'Incorrect padding' ); } } else { $encodedString = \rtrim($encodedString, '='); $srcLen = Binary::safeStrlen($encodedString); } $err = 0; $dest = ''; // Main loop (no padding): for ($i = 0; $i + 4 <= $srcLen; $i += 4) { /** @var array $chunk */ $chunk = \unpack('C*', Binary::safeSubstr($encodedString, $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($encodedString, $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/src/Hex.php000064400000012176150225423600013313 0ustar00 $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 $encodedString * @param bool $strictPadding * @return string (raw binary) * @throws \RangeException */ public static function decode(string $encodedString, 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($encodedString); /** @var int $state */ $state = 0; if (($hex_len & 1) !== 0) { if ($strictPadding) { throw new \RangeException( 'Expected an even number of hexadecimal characters' ); } else { $encodedString = '0' . $encodedString; ++$hex_len; } } /** @var array $chunk */ $chunk = \unpack('C*', $encodedString); 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( 'Expected hexadecimal character' ); } /** @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/src/Base64UrlSafe.php000064400000006234150225423600015073 0ustar00 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/src/Base64DotSlash.php000064400000005737150225423600015262 0ustar00 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/src/Base64DotSlashOrdered.php000064400000005340150225423600016555 0ustar00 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/src/Base32.php000064400000037340150225423600013606 0ustar00 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/src/EncoderInterface.php000064400000003700150225423600015760 0ustar00 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); } }random_compat/LICENSE000064400000002112150225423600010367 0ustar00The MIT License (MIT) Copyright (c) 2015 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. random_compat/other/build_phar.php000064400000003141150225423600013330 0ustar00buildFromDirectory(dirname(__DIR__).'/lib'); rename( dirname(__DIR__).'/lib/index.php', dirname(__DIR__).'/lib/random.php' ); /** * If we pass an (optional) path to a private key as a second argument, we will * sign the Phar with OpenSSL. * * If you leave this out, it will produce an unsigned .phar! */ if ($argc > 1) { if (!@is_readable($argv[1])) { echo 'Could not read the private key file:', $argv[1], "\n"; exit(255); } $pkeyFile = file_get_contents($argv[1]); $private = openssl_get_privatekey($pkeyFile); if ($private !== false) { $pkey = ''; openssl_pkey_export($private, $pkey); $phar->setSignatureAlgorithm(Phar::OPENSSL, $pkey); /** * Save the corresponding public key to the file */ if (!@is_readable($dist.'/random_compat.phar.pubkey')) { $details = openssl_pkey_get_details($private); file_put_contents( $dist.'/random_compat.phar.pubkey', $details['key'] ); } } else { echo 'An error occurred reading the private key from OpenSSL.', "\n"; exit(255); } } random_compat/psalm.xml000064400000001124150225423600011222 0ustar00 random_compat/psalm-autoload.php000064400000000347150225423600013025 0ustar00= 7" }, "require-dev": { "vimeo/psalm": "^1", "phpunit/phpunit": "4.*|5.*" }, "suggest": { "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." } } random_compat/dist/random_compat.phar.pubkey000064400000000327150225423600015330 0ustar00-----BEGIN PUBLIC KEY----- MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEEd+wCqJDrx5B4OldM0dQE0ZMX+lx1ZWm pui0SUqD4G29L3NGsz9UhJ/0HjBdbnkhIK5xviT0X5vtjacF6ajgcCArbTB+ds+p +h7Q084NuSuIpNb6YPfoUFgC/CL9kAoc -----END PUBLIC KEY----- random_compat/dist/random_compat.phar.pubkey.asc000064400000000750150225423600016075 0ustar00-----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (MingW32) iQEcBAABAgAGBQJWtW1hAAoJEGuXocKCZATaJf0H+wbZGgskK1dcRTsuVJl9IWip QwGw/qIKI280SD6/ckoUMxKDCJiFuPR14zmqnS36k7N5UNPnpdTJTS8T11jttSpg 1LCmgpbEIpgaTah+cELDqFCav99fS+bEiAL5lWDAHBTE/XPjGVCqeehyPYref4IW NDBIEsvnHPHPLsn6X5jq4+Yj5oUixgxaMPiR+bcO4Sh+RzOVB6i2D0upWfRXBFXA NNnsg9/zjvoC7ZW73y9uSH+dPJTt/Vgfeiv52/v41XliyzbUyLalf02GNPY+9goV JHG1ulEEBJOCiUD9cE1PUIJwHA/HqyhHIvV350YoEFiHl8iSwm7SiZu5kPjaq74= =B6+8 -----END PGP SIGNATURE----- random_compat/build-phar.sh000064400000000206150225423600011747 0ustar00#!/usr/bin/env bash basedir=$( dirname $( readlink -f ${BASH_SOURCE[0]} ) ) php -dphar.readonly=0 "$basedir/other/build_phar.php" $*