This commit is contained in:
Xes
2025-08-14 22:41:49 +02:00
parent 2de81ccc46
commit 8ce45119b6
39774 changed files with 4309466 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
vendor
composer.lock

58
vendor/paragonie/random-lib/.php_cs vendored Normal file
View File

@@ -0,0 +1,58 @@
<?php
$header = <<<'EOF'
The RandomLib library for securely generating random numbers and strings in PHP
@author Anthony Ferrara <ircmaxell@ircmaxell.com>
@copyright 2011 The Authors
@license http://www.opensource.org/licenses/mit-license.html MIT License
@version Build @@version@@
EOF;
Symfony\CS\Fixer\Contrib\HeaderCommentFixer::setHeader($header);
return Symfony\CS\Config\Config::create()
->level(Symfony\CS\FixerInterface::PSR2_LEVEL)
->fixers([
'align_double_arrow',
'array_element_no_space_before_comma',
'array_element_white_space_after_comma',
'declare_equal_normalize',
'extra_empty_lines',
'header_comment',
'list_commas',
'multiline_array_trailing_comma',
'new_with_braces',
'no_blank_lines_before_namespace',
'no_empty_comment',
'no_empty_lines_after_phpdocs',
'no_empty_phpdoc',
'no_empty_statement',
'object_operator',
'ordered_use',
'php_unit_dedicate_assert',
'phpdoc_indent',
'phpdoc_order',
'phpdoc_params',
'phpdoc_scalar',
'phpdoc_separation',
'remove_leading_slash_use',
'remove_lines_between_uses',
'return',
'self_accessor',
'short_bool_cast',
'short_scalar_cast',
'single_blank_line_before_namespace',
'spaces_before_semicolon',
'ternary_spaces',
'trim_array_spaces',
'unneeded_control_parentheses',
'unused_use',
'whitespacey_lines',
])
->finder(
Symfony\CS\Finder\DefaultFinder::create()
->in(__DIR__ . "/lib")
->in(__DIR__ . "/test")
)
;

View File

@@ -0,0 +1,80 @@
filter:
paths:
- lib/*
checks:
php:
code_rating: true
duplication: true
variable_existence: true
useless_calls: true
use_statement_alias_conflict: true
unused_variables: true
unused_properties: true
unused_parameters: true
unused_methods: true
unreachable_code: true
sql_injection_vulnerabilities: true
security_vulnerabilities: true
precedence_mistakes: true
precedence_in_conditions: true
parameter_non_unique: true
no_property_on_interface: true
no_non_implemented_abstract_methods: true
deprecated_code_usage: true
closure_use_not_conflicting: true
closure_use_modifiable: true
avoid_useless_overridden_methods: true
avoid_conflicting_incrementers: true
assignment_of_null_return: true
verify_access_scope_valid: true
verify_argument_usable_as_reference: true
verify_property_names: true
use_self_instead_of_fqcn: true
uppercase_constants: true
too_many_arguments: true
spacing_of_function_arguments: true
spacing_around_non_conditional_operators: true
spacing_around_conditional_operators: true
space_after_cast: true
single_namespace_per_use: true
scope_indentation:
spaces_per_level: '4'
return_doc_comments: true
return_doc_comment_if_not_inferrable: true
require_scope_for_properties: true
require_scope_for_methods: true
require_php_tag_first: true
property_assignments: true
properties_in_camelcaps: true
php5_style_constructor: true
parameters_in_camelcaps: true
parameter_doc_comments: true
param_doc_comment_if_not_inferrable: true
optional_parameters_at_the_end: true
one_class_per_file: true
no_unnecessary_function_call_in_for_loop: true
no_unnecessary_final_modifier: true
no_trailing_whitespace: true
no_space_inside_cast_operator: true
no_space_before_semicolon: true
no_short_open_tag: true
no_commented_out_code: true
newline_at_end_of_file: true
missing_arguments: true
lowercase_php_keywords: true
lowercase_basic_constants: true
function_in_camel_caps: true
function_body_start_on_same_line: true
ensure_lower_case_builtin_functions: true
classes_in_camel_caps: true
blank_line_after_namespace_declaration: true
avoid_usage_of_logical_operators: true
avoid_todo_comments: true
avoid_tab_indentation: true
avoid_superglobals: true
avoid_fixme_comments: true
avoid_corrupting_byteorder_marks: true
avoid_duplicate_types: true
avoid_closing_tag: true
avoid_aliased_php_functions: true
argument_type_checks: true

41
vendor/paragonie/random-lib/.travis.yml vendored Normal file
View File

@@ -0,0 +1,41 @@
language: php
sudo: required
matrix:
fast_finish: true
include:
- php: "5.3"
env: USE_PSALM=0
dist: precise
- php: "5.4"
env: USE_PSALM=0
- php: "5.5"
env: USE_PSALM=0
- php: "5.6"
env: USE_PSALM=1
- php: "7.0"
env: USE_PSALM=1
- php: "7.1"
env: USE_PSALM=1
- php: "7.2"
env: USE_PSALM=1
- php: "nightly"
env: USE_PSALM=1
- php: "master"
env: USE_PSALM=1
- php: "hhvm"
env: USE_PSALM=1
allow_failures:
- php: "master"
- php: "nightly"
before_script:
- travis_retry composer self-update
- if [[ $USE_PSALM -eq 1 ]]; then composer require --dev "vimeo/psalm:dev-master"; fi
- travis_retry composer install --prefer-source
script:
- make lint
- make test
- if [[ $USE_PSALM -eq 1 ]]; then make typecheck; fi

19
vendor/paragonie/random-lib/LICENSE vendored Normal file
View File

@@ -0,0 +1,19 @@
Copyright (c) 2011 The Authors
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.

30
vendor/paragonie/random-lib/Makefile vendored Normal file
View File

@@ -0,0 +1,30 @@
.PHONY: all
all: build
.PHONY: build
build: lint cs test
lintfiles := $(shell find lib test -type f -iname '*.php')
.PHONY: ${lintfiles}
${lintfiles}:
php -l $@
.PHONY: lint
lint: $(lintfiles)
.PHONY: cs
cs:
vendor/bin/php-cs-fixer --quiet --no-interaction fix; true
.PHONY: test
test:
vendor/bin/phpunit
.PHONY: typecheck
typecheck:
vendor/bin/psalm

146
vendor/paragonie/random-lib/README.md vendored Normal file
View File

@@ -0,0 +1,146 @@
RandomLib
=========
[![Build Status](https://travis-ci.org/paragonie/RandomLib.svg?branch=master)](https://travis-ci.org/paragonie/RandomLib)
[![Latest Stable Version](https://poser.pugx.org/paragonie/RandomLib/v/stable)](https://packagist.org/packages/paragonie/RandomLib)
[![Latest Unstable Version](https://poser.pugx.org/paragonie/RandomLib/v/unstable)](https://packagist.org/packages/paragonie/RandomLib)
[![License](https://poser.pugx.org/paragonie/RandomLib/license)](https://packagist.org/packages/paragonie/RandomLib)
A library for generating random numbers and strings of various strengths.
This library is useful in security contexts.
> Note: This is a fork of [Anthony Ferrara's `RandomLib`](https://github.com/ircmaxell/RandomLib),
> maintained by [Paragon Initiative Enterprises](https://paragonie.com).
Install
-------
Via Composer
```sh
$ composer require paragonie/random-lib
```
Usage
-----
### Factory
A factory is used to get generators of varying strength:
```php
$factory = new RandomLib\Factory;
$generator = $factory->getGenerator(new SecurityLib\Strength(SecurityLib\Strength::MEDIUM));
```
A factory can be configured with additional mixers and sources but can be
used out of the box to create both medium and low strength generators.
Convenience methods are provided for creating high, medium, and low
strength generators. Example:
```php
$generator = $factory->getMediumStrengthGenerator();
```
#### $factory->getLowStrengthGenerator()
Convenience method to get a low strength random number generator.
Low Strength should be used anywhere that random strings are needed in a
non-cryptographical setting. They are not strong enough to be used as
keys or salts. They are however useful for one-time use tokens.
#### $factory->getMediumStrengthGenerator()
Convenience method to get a medium strength random number generator.
Medium Strength should be used for most needs of a cryptographic nature.
They are strong enough to be used as keys and salts. However, they do
take some time and resources to generate, so they should not be over-used
#### $factory->getHighStrengthGenerator()
Convenience method to get a high strength random number generator.
High Strength keys should ONLY be used for generating extremely strong
cryptographic keys. Generating them is very resource intensive and may
take several minutes or more depending on the requested size.
### Generator
A generator is used to generate random numbers and strings.
Example:
```php
// Generate a random string that is 32 bytes in length.
$bytes = $generator->generate(32);
// Generate a whole number between 5 and 15.
$randomInt = $generator->generateInt(5, 15);
// Generate a 32 character string that only contains the letters
// 'a', 'b', 'c', 'd', 'e', and 'f'.
$randomString = $generator->generateString(32, 'abcdef');
```
#### $generator->generate($size)
Generate a random byte string of the requested size.
#### $generator->generateInt($min = 0, $max = PHP_INT_MAX)
Generate a random integer with the given range. If range (`$max - $min`)
is zero, `$max` will be used.
#### $generator->generateString($length, $characters = '')
Generate a random string of specified length.
This uses the supplied character list for generating the new result
string. The list of characters should be specified as a string containing
each allowed character.
If no character list is specified, the following list of characters is used:
0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/
**Examples:**
```php
// Give the character list 'abcdef':
print $generator->generateString(32, 'abcdef')."\n";
// One would expect to receive output that only contained those
// characters:
//
// adaeabecfbddcdaeedaedfbbcdccccfe
// adfbfdbfddadbfcbbefebcacbefafffa
// ceeadbcabecbccacdcaabbdccfadbafe
// abadcffabdcacdbcbafcaecabafcdbbf
// dbdbddacdeaceabfaefcbfafebcacdca
```
License
-------
MIT, see LICENSE.
Community
---------
If you have questions or want to help out, join us in the **#phpc**
channel on **irc.freenode.net**.
Security Vulnerabilities
========================
If you have found a security issue, please contact the author directly at
[security@paragonie.com](mailto:security@paragonie.com).

View File

@@ -0,0 +1,41 @@
{
"name": "paragonie/random-lib",
"type": "library",
"description": "A Library For Generating Secure Random Numbers",
"keywords": ["random", "random-numbers", "random-strings", "cryptography"],
"homepage": "https://github.com/ircmaxell/RandomLib",
"license": "MIT",
"authors": [
{
"name": "Paragon Initiative Enterprises",
"email": "security@paragonie.com",
"homepage": "https://paragonie.com"
},
{
"name": "Anthony Ferrara",
"email": "ircmaxell@ircmaxell.com",
"homepage": "http://blog.ircmaxell.com"
}
],
"require-dev": {
"mikey179/vfsStream": "^1.6",
"friendsofphp/php-cs-fixer": "^1.11",
"phpunit/phpunit": "^4.8 || >=5.0.0 <5.4"
},
"require": {
"ircmaxell/security-lib": "^1.1",
"paragonie/random_compat": "^2",
"paragonie/sodium_compat": "^1.3",
"php": ">=5.3.2"
},
"autoload": {
"psr-0": {
"RandomLib": "lib"
}
},
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
}
}
}

View File

@@ -0,0 +1,198 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Mcrypt abstract mixer class
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @copyright 2013 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib;
/**
* The mcrypt abstract mixer class
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Chris Smith <chris@cs278.org>
* @author Paragon Initiative Enterprises <security@paragonie.com>
*/
abstract class AbstractMcryptMixer extends AbstractMixer
{
/**
* mcrypt module resource
*
* @var resource
*/
private $mcrypt;
/**
* Block size of cipher
*
* @var int
*/
private $blockSize;
/**
* Cipher initialization vector
*
* @var string
*/
private $initv;
/**
* {@inheritdoc}
*/
public static function test()
{
return extension_loaded('mcrypt');
}
/**
* @return bool
*/
public static function advisable()
{
return static::test() && PHP_VERSION_ID < 70100;
}
/**
* Construct mcrypt mixer
* @psalm-suppress UndefinedConstant
*/
public function __construct()
{
$this->mcrypt = mcrypt_module_open($this->getCipher(), '', MCRYPT_MODE_ECB, '');
$this->blockSize = mcrypt_enc_get_block_size($this->mcrypt);
$this->initv = str_repeat(chr(0), mcrypt_enc_get_iv_size($this->mcrypt));
}
/**
* Performs cleanup
*/
public function __destruct()
{
if ($this->mcrypt) {
mcrypt_module_close($this->mcrypt);
}
}
/**
* Fetch the cipher for mcrypt.
*
* @return string
*/
abstract protected function getCipher();
/**
* {@inheritdoc}
*/
protected function getPartSize()
{
return $this->blockSize;
}
/**
* {@inheritdoc}
*/
protected function mixParts1($part1, $part2)
{
if (!\is_string($part1)) {
throw new \InvalidArgumentException('Expected a string');
}
if (!\is_string($part2)) {
throw new \InvalidArgumentException('Expected a string');
}
return $this->encryptBlock($part1, $part2);
}
/**
* {@inheritdoc}
*/
protected function mixParts2($part1, $part2)
{
if (!\is_string($part1)) {
throw new \InvalidArgumentException('Expected a string');
}
if (!\is_string($part2)) {
throw new \InvalidArgumentException('Expected a string');
}
return $this->decryptBlock($part2, $part1);
}
/**
* Encrypts a block using the suppied key
*
* @param string $input Plaintext to encrypt
* @param string $key Encryption key
*
* @return string Resulting ciphertext
*/
private function encryptBlock($input, $key)
{
if (!$input && !$key) {
return '';
}
$this->prepareCipher($key);
$result = mcrypt_generic($this->mcrypt, $input);
mcrypt_generic_deinit($this->mcrypt);
return $result;
}
/**
* Derypts a block using the suppied key
*
* @param string $input Ciphertext to decrypt
* @param string $key Encryption key
*
* @return string Resulting plaintext
*/
private function decryptBlock($input, $key)
{
if (!$input && !$key) {
return '';
}
$this->prepareCipher($key);
$result = mdecrypt_generic($this->mcrypt, $input);
mcrypt_generic_deinit($this->mcrypt);
return $result;
}
/**
* Sets up the mcrypt module
*
* @param string $key
*
* @return void
*/
private function prepareCipher($key)
{
if (0 !== mcrypt_generic_init($this->mcrypt, $key, $this->initv)) {
throw new \RuntimeException('Failed to prepare mcrypt module');
}
}
}

View File

@@ -0,0 +1,191 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* An abstract mixer to implement a common mixing strategy
*
* PHP version 5.3
*
* @category PHPSecurityLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib;
use SecurityLib\Util;
/**
* An abstract mixer to implement a common mixing strategy
*
* @see http://tools.ietf.org/html/rfc4086#section-5.2
*
* @category PHPSecurityLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
*/
abstract class AbstractMixer implements \RandomLib\Mixer
{
/**
* Get the block size (the size of the individual blocks used for the mixing)
*
* @return int The block size
*/
abstract protected function getPartSize();
/**
* Mix 2 parts together using one method
*
* @param string $part1 The first part to mix
* @param string $part2 The second part to mix
*
* @return string The mixed data
*/
abstract protected function mixParts1($part1, $part2);
/**
* Mix 2 parts together using another different method
*
* @param string $part1 The first part to mix
* @param string $part2 The second part to mix
*
* @return string The mixed data
*/
abstract protected function mixParts2($part1, $part2);
/**
* @return bool
*/
public static function advisable()
{
return static::test();
}
/**
* Mix the provided array of strings into a single output of the same size
*
* All elements of the array should be the same size.
*
* @param array<int, string> $parts The parts to be mixed
*
* @return string The mixed result
* @psalm-suppress MixedArgument
*/
public function mix(array $parts)
{
if (empty($parts)) {
return '';
}
/** @var int $len */
$len = Util::safeStrlen($parts[0]);
/** @var array<int, array<int, string>> $parts */
$parts = $this->normalizeParts($parts);
$stringSize = \count($parts[0]);
$partsSize = \count($parts);
/** @var string $result */
$result = '';
/** @var int $offset */
$offset = 0;
for ($i = 0; $i < $stringSize; ++$i) {
/** @var string $stub */
$stub = (string) $parts[$offset][$i];
for ($j = 1; $j < $partsSize; ++$j) {
/** @var string $newKey */
$newKey = $parts[($j + $offset) % $partsSize][$i];
//Alternately mix the output for each source
if ($j % 2 == 1) {
$stub ^= $this->mixParts1($stub, $newKey);
} else {
$stub ^= $this->mixParts2($stub, $newKey);
}
}
$result .= $stub;
$offset = ($offset + 1) % $partsSize;
}
/** @var string $final */
$final = Util::safeSubstr($result, 0, $len);
return $final;
}
/**
* Normalize the part array and split it block part size.
*
* This will make all parts the same length and a multiple
* of the part size
*
* @param array<int, string> $parts The parts to normalize
*
* @return array The normalized and split parts
* @psalm-suppress MissingClosureReturnType
* @psalm-suppress UntypedParam
* @psalm-suppress MissingArgument
*/
protected function normalizeParts(array $parts)
{
if (empty($parts)) {
return $parts;
}
$blockSize = $this->getPartSize();
$callback =
/**
* @var callable $callback
* @param string $value
* @return int
*/
function ($value) {
return (int) Util::safeStrlen($value);
};
$mapped = array_map($callback, $parts);
if (count($mapped) < 1) {
return array();
}
/** @var int $maxSize */
$maxSize = count($mapped) > 1
? max($mapped)
: array_shift($mapped);
if ($maxSize % $blockSize != 0) {
$maxSize += $blockSize - ($maxSize % $blockSize);
}
foreach ($parts as &$part) {
$part = $this->str_pad($part, $maxSize, chr(0));
$part = str_split($part, $blockSize);
}
return $parts;
}
/**
* @param string $string
* @param int $size
* @param string $character
* @return string
*/
private function str_pad($string, $size, $character)
{
$start = Util::safeStrlen($string);
$inc = Util::safeStrlen($character);
for ($i = $start; $i < $size; $i+= $inc) {
$string = $string . $character;
}
return Util::safeSubstr($string, 0, $size);
}
}

View File

@@ -0,0 +1,70 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* PHP version 5.3
*
* @category PHPSecurityLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib;
use SecurityLib\Strength;
/**
* An abstract mixer to implement a common mixing strategy
*
* @category PHPSecurityLib
* @package Random
*/
abstract class AbstractSource implements \RandomLib\Source
{
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
return new Strength(Strength::VERYLOW);
}
/**
* If the source is currently available.
* Reasons might be because the library is not installed
*
* @return bool
*/
public static function isSupported()
{
return true;
}
/**
* Returns a string of zeroes, useful when no entropy is available.
*
* @param int $size The size of the requested random string
*
* @return string A string of the requested size
*/
protected static function emptyValue($size)
{
return (string) \str_repeat(\chr(0), $size);
}
}

View File

@@ -0,0 +1,290 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Random Factory
*
* Use this factory to instantiate random number generators, sources and mixers.
*
* PHP version 5.3
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib;
use SecurityLib\Strength;
/**
* The Random Factory
*
* Use this factory to instantiate random number generators, sources and mixers.
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
*/
class Factory extends \SecurityLib\AbstractFactory
{
/**
* @var array<int, Mixer> A list of available random number mixing strategies
*/
protected $mixers = array();
/**
* @var array<int, Source> A list of available random number sources
*/
protected $sources = array();
/**
* Build a new instance of the factory, loading core mixers and sources
*
* @return void
*/
public function __construct()
{
$this->loadMixers();
$this->loadSources();
}
/**
* Get a generator for the requested strength
*
* @param Strength $strength The requested strength of the random number
*
* @throws \RuntimeException If an appropriate mixing strategy isn't found
*
* @return Generator The instantiated generator
*/
public function getGenerator(\SecurityLib\Strength $strength)
{
$sources = $this->findSources($strength);
$mixer = $this->findMixer($strength);
return new Generator($sources, $mixer);
}
/**
* Get a high strength random number generator
*
* High Strength keys should ONLY be used for generating extremely strong
* cryptographic keys. Generating them is very resource intensive and may
* take several minutes or more depending on the requested size.
*
* @return Generator The instantiated generator
*/
public function getHighStrengthGenerator()
{
return $this->getGenerator(new Strength(Strength::HIGH));
}
/**
* Get a low strength random number generator
*
* Low Strength should be used anywhere that random strings are needed in a
* non-cryptographical setting. They are not strong enough to be used as
* keys or salts. They are however useful for one-time use tokens.
*
* @return Generator The instantiated generator
*/
public function getLowStrengthGenerator()
{
return $this->getGenerator(new Strength(Strength::LOW));
}
/**
* Get a medium strength random number generator
*
* Medium Strength should be used for most needs of a cryptographic nature.
* They are strong enough to be used as keys and salts. However, they do
* take some time and resources to generate, so they should not be over-used
*
* @return Generator The instantiated generator
*/
public function getMediumStrengthGenerator()
{
return $this->getGenerator(new Strength(Strength::MEDIUM));
}
/**
* Get all loaded mixing strategies
*
* @return array<int, Mixer> An array of mixers
*/
public function getMixers()
{
return $this->mixers;
}
/**
* Get all loaded random number sources
*
* @return array<int, Source> An array of sources
*/
public function getSources()
{
return $this->sources;
}
/**
* Register a mixing strategy for this factory instance
*
* @param string $name The name of the stategy
* @param string $class The class name of the implementation
*
* @return Factory $this The current factory instance
*/
public function registerMixer($name, $class)
{
$this->registerType(
'mixers',
__NAMESPACE__ . '\\Mixer',
$name,
$class
);
return $this;
}
/**
* Register a random number source for this factory instance
*
* Note that this class must implement the Source interface
*
* @param string $name The name of the stategy
* @param string $class The class name of the implementation
*
* @return Factory $this The current factory instance
*/
public function registerSource($name, $class)
{
$this->registerType(
'sources',
__NAMESPACE__ . '\\Source',
$name,
$class
);
return $this;
}
/**
* Find a sources based upon the requested strength
*
* @param Strength $strength The strength mixer to find
*
* @throws \RuntimeException if a valid source cannot be found
*
* @return array<int, Source> The found source
*/
protected function findSources(\SecurityLib\Strength $strength)
{
/** @var array<int, Source> $sources */
$sources = array();
foreach ($this->getSources() as $source) {
if ($strength->compare($source::getStrength()) <= 0 && $source::isSupported()) {
/** @var Source $obj */
$obj = new $source();
if ($obj instanceof Source) {
$sources[] = $obj;
}
}
}
if (0 === count($sources)) {
throw new \RuntimeException('Could not find sources');
}
return $sources;
}
/**
* Find a mixer based upon the requested strength
*
* @param Strength $strength The strength mixer to find
*
* @throws \RuntimeException if a valid mixer cannot be found
*
* @return Mixer The found mixer
*/
protected function findMixer(\SecurityLib\Strength $strength)
{
/** @var Mixer|null $newMixer */
$newMixer = null;
/** @var Mixer|null $fallback */
$fallback = null;
foreach ($this->getMixers() as $mixer) {
if (!$mixer::test() || !$mixer::advisable()) {
continue;
}
if ($strength->compare($mixer::getStrength()) == 0) {
/** @var Mixer $newMixer */
$newMixer = new $mixer();
} elseif ($strength->compare($mixer::getStrength()) == 1) {
/** @var Mixer $fallback */
$fallback = new $mixer();
}
}
if (\is_null($newMixer)) {
if (\is_null($fallback)) {
throw new \RuntimeException('Could not find mixer');
} elseif (!($fallback instanceof Mixer)) {
throw new \RuntimeException('Invalid Mixer');
}
return $fallback;
} elseif (!($newMixer instanceof Mixer)) {
throw new \RuntimeException('Invalid Mixer');
}
return $newMixer;
}
/**
* Load all core mixing strategies
*
* @return void
* @psalm-suppress InvalidArgument
*/
protected function loadMixers()
{
$this->loadFiles(
__DIR__ . '/Mixer',
__NAMESPACE__ . '\\Mixer\\',
array($this, 'registerMixer')
);
}
/**
* Load all core random number sources
*
* @return void
* @psalm-suppress InvalidArgument
*/
protected function loadSources()
{
$this->loadFiles(
__DIR__ . '/Source',
__NAMESPACE__ . '\\Source\\',
array($this, 'registerSource')
);
}
}

View File

@@ -0,0 +1,386 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Random Number Generator Class
*
* Use this factory to generate cryptographic quality random numbers (strings)
*
* PHP version 5.3
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @author Timo Hamina
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib;
use SecurityLib\Util;
/**
* The Random Number Generator Class
*
* Use this factory to generate cryptographic quality random numbers (strings)
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @author Timo Hamina
*/
class Generator
{
/**
* @const Flag for uppercase letters
*/
const CHAR_UPPER = 1;
/**
* @const Flag for lowercase letters
*/
const CHAR_LOWER = 2;
/**
* @const Flag for alpha characters (combines UPPER + LOWER)
*/
const CHAR_ALPHA = 3; // CHAR_UPPER | CHAR_LOWER
/**
* @const Flag for digits
*/
const CHAR_DIGITS = 4;
/**
* @const Flag for alpha numeric characters
*/
const CHAR_ALNUM = 7; // CHAR_ALPHA | CHAR_DIGITS
/**
* @const Flag for uppercase hexadecimal symbols
*/
const CHAR_UPPER_HEX = 12; // 8 | CHAR_DIGITS
/**
* @const Flag for lowercase hexidecimal symbols
*/
const CHAR_LOWER_HEX = 20; // 16 | CHAR_DIGITS
/**
* @const Flag for base64 symbols
*/
const CHAR_BASE64 = 39; // 32 | CHAR_ALNUM
/**
* @const Flag for additional symbols accessible via the keyboard
*/
const CHAR_SYMBOLS = 64;
/**
* @const Flag for brackets
*/
const CHAR_BRACKETS = 128;
/**
* @const Flag for punctuation marks
*/
const CHAR_PUNCT = 256;
/**
* @const Flag for upper/lower-case and digits but without "B8G6I1l|0OQDS5Z2"
*/
const EASY_TO_READ = 512;
/**
* @var Mixer The mixing strategy to use for this generator instance
*/
protected $mixer = null;
/**
* @var array<int, Source> An array of random number sources to use for this generator
*/
protected $sources = array();
/**
* @var array<int, string> The different characters, by Flag
*/
protected $charArrays = array(
self::CHAR_UPPER => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
self::CHAR_LOWER => 'abcdefghijklmnopqrstuvwxyz',
self::CHAR_DIGITS => '0123456789',
self::CHAR_UPPER_HEX => 'ABCDEF',
self::CHAR_LOWER_HEX => 'abcdef',
self::CHAR_BASE64 => '+/',
self::CHAR_SYMBOLS => '!"#$%&\'()* +,-./:;<=>?@[\]^_`{|}~',
self::CHAR_BRACKETS => '()[]{}<>',
self::CHAR_PUNCT => ',.;:',
);
/**
* @internal
* @private
* @const string Ambiguous characters for "Easy To Read" sets
*/
const AMBIGUOUS_CHARS = 'B8G6I1l|0OQDS5Z2()[]{}:;,.';
/**
* Build a new instance of the generator
*
* @param array<int, Source> $sources An array of random data sources to use
* @param Mixer $mixer The mixing strategy to use for this generator
*/
public function __construct(array $sources, Mixer $mixer)
{
foreach ($sources as $source) {
$this->addSource($source);
}
$this->mixer = $mixer;
}
/**
* Add a random number source to the generator
*
* @param Source $source The random number source to add
*
* @return Generator $this The current generator instance
*/
public function addSource(Source $source)
{
$this->sources[] = $source;
return $this;
}
/**
* Generate a random number (string) of the requested size
*
* @param int $size The size of the requested random number
*
* @return string The generated random number (string)
*/
public function generate($size)
{
$seeds = array();
foreach ($this->sources as $source) {
if ($source instanceof Source) {
$seeds[] = $source->generate($size);
}
}
return $this->mixer->mix($seeds);
}
/**
* Generate a random integer with the given range
*
* @param int $min The lower bound of the range to generate
* @param int $max The upper bound of the range to generate
*
* @return int The generated random number within the range
*/
public function generateInt($min = 0, $max = PHP_INT_MAX)
{
$tmp = (int) max($max, $min);
$min = (int) min($max, $min);
$max = $tmp;
$range = $max - $min;
if ($range == 0) {
return $max;
} elseif ($range > PHP_INT_MAX || is_float($range) || $range < 0) {
/**
* This works, because PHP will auto-convert it to a float at this point,
* But on 64 bit systems, the float won't have enough precision to
* actually store the difference, so we need to check if it's a float
* and hence auto-converted...
*/
throw new \RangeException(
'The supplied range is too great to generate'
);
}
$bits = $this->countBits($range) + 1;
$bytes = (int) \max(\ceil($bits / 8), 1);
if ($bits == 63) {
/**
* Fixes issue #22
*
* @see https://github.com/ircmaxell/RandomLib/issues/22
*/
$mask = 0x7fffffffffffffff;
} else {
$mask = (int) ((1 << $bits) - 1);
}
/**
* The mask is a better way of dropping unused bits. Basically what it does
* is to set all the bits in the mask to 1 that we may need. Since the max
* range is PHP_INT_MAX, we will never need negative numbers (which would
* have the MSB set on the max int possible to generate). Therefore we
* can just mask that away. Since pow returns a float, we need to cast
* it back to an int so the mask will work.
*
* On a 64 bit platform, that means that PHP_INT_MAX is 2^63 - 1. Which
* is also the mask if 63 bits are needed (by the log(range, 2) call).
* So if the computed result is negative (meaning the 64th bit is set), the
* mask will correct that.
*
* This turns out to be slightly better than the shift as we don't need to
* worry about "fixing" negative values.
*/
do {
$test = $this->generate($bytes);
/** @var int $result */
$result = \hexdec(\bin2hex($test)) & $mask;
} while ($result > $range);
return $result + $min;
}
/**
* Generate a random string of specified length.
*
* This uses the supplied character list for generating the new result
* string.
*
* @param int $length The length of the generated string
* @param int|string $characters String: An optional list of characters to use
* Integer: Character flags
*
* @return string The generated random string
*/
public function generateString($length, $characters = '')
{
if (is_int($characters)) {
// Combine character sets
$characters = $this->expandCharacterSets($characters);
}
if ($length == 0 || strlen($characters) == 1) {
return '';
} elseif (empty($characters)) {
// Default to base 64
$characters = $this->expandCharacterSets(self::CHAR_BASE64);
}
/**
* @var string $characters
*/
// determine how many bytes to generate
// This is basically doing floor(log(strlen($characters)))
// But it's fixed to work properly for all numbers
$len = strlen($characters);
// The max call here fixes an issue where we under-generate in cases
// where less than 8 bits are needed to represent $len
/** @var int $bytes */
$bytes = (int) ($length * ceil(($this->countBits($len)) / 8));
// determine mask for valid characters
$mask = 256 - (256 % $len);
$result = '';
do {
$rand = $this->generate($bytes);
for ($i = 0; $i < $bytes; $i++) {
if (\ord($rand[$i]) >= $mask) {
continue;
}
/** @var int $idx */
$idx = (int) ((int) \ord($rand[$i]) % (int) ($len));
$result .= (string) ($characters[$idx]);
}
} while (Util::safeStrlen($result) < $length);
// We may over-generate, since we always use the entire buffer
return Util::safeSubstr($result, 0, $length);
}
/**
* Get the Mixer used for this instance
*
* @return Mixer the current mixer
*/
public function getMixer()
{
return $this->mixer;
}
/**
* Get the Sources used for this instance
*
* @return array<int, Source> the current mixer
*/
public function getSources()
{
return $this->sources;
}
/**
* Count the minimum number of bits to represent the provided number
*
* This is basically floor(log($number, 2))
* But avoids float precision issues
*
* @param int $number The number to count
*
* @return int The number of bits
*/
protected function countBits($number)
{
$log2 = 0;
while ($number >>= 1) {
$log2++;
}
return $log2;
}
/**
* Expand a character set bitwise spec into a string character set
*
* This will also replace EASY_TO_READ characters if the flag is set
*
* @param int $spec The spec to expand (bitwise combination of flags)
*
* @return string The expanded string
*/
protected function expandCharacterSets($spec)
{
/** @var string $combined */
$combined = '';
if ($spec == self::EASY_TO_READ) {
$spec |= self::CHAR_ALNUM;
}
foreach ($this->charArrays as $flag => $chars) {
if ($flag == self::EASY_TO_READ) {
// handle this later
continue;
}
if (($spec & $flag) === $flag) {
$combined .= $chars;
}
}
if ($spec & self::EASY_TO_READ) {
// remove ambiguous characters
$combined = \str_replace(
\str_split(self::AMBIGUOUS_CHARS),
'',
$combined
);
}
return (string) \count_chars($combined, 3);
}
}

View File

@@ -0,0 +1,77 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Mixer strategy interface.
*
* All mixing strategies must implement this interface
*
* PHP version 5.3
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib;
/**
* The Mixer strategy interface.
*
* All mixing strategies must implement this interface
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @codeCoverageIgnore
*/
interface Mixer
{
/**
* Return an instance of Strength indicating the strength of the mixer
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength();
/**
* Test to see if the mixer is available
*
* @return bool If the mixer is available on the system
*/
public static function test();
/**
* Even if the mixer is available,
*
* @return bool
*/
public static function advisable();
/**
* Mix the provided array of strings into a single output of the same size
*
* All elements of the array should be the same size.
*
* @param array $parts The parts to be mixed
*
* @return string The mixed result
*/
public function mix(array $parts);
}

View File

@@ -0,0 +1,126 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Hash medium strength mixer class
*
* This class implements a mixer based upon the recommendations in RFC 4086
* section 5.2
*
* PHP version 5.3
*
* @see http://tools.ietf.org/html/rfc4086#section-5.2
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Mixer;
use SecurityLib\Strength;
use SecurityLib\Util;
/**
* The Hash medium strength mixer class
*
* This class implements a mixer based upon the recommendations in RFC 4086
* section 5.2
*
* @see http://tools.ietf.org/html/rfc4086#section-5.2
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
*/
class Hash extends \RandomLib\AbstractMixer
{
/**
* @var string The hash instance to use
*/
protected $hash = null;
/**
* Build the hash mixer
*
* @param string $hash The hash instance to use (defaults to sha512)
*
* @return void
*/
public function __construct($hash = 'sha512')
{
$this->hash = $hash;
}
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
return new Strength(Strength::MEDIUM);
}
/**
* Test to see if the mixer is available
*
* @return bool If the mixer is available on the system
*/
public static function test()
{
return true;
}
/**
* Get the block size (the size of the individual blocks used for the mixing)
*
* @return int The block size
*/
protected function getPartSize()
{
return Util::safeStrlen(hash($this->hash, '', true));
}
/**
* Mix 2 parts together using one method
*
* @param string $part1 The first part to mix
* @param string $part2 The second part to mix
*
* @return string The mixed data
*/
protected function mixParts1($part1, $part2)
{
return hash_hmac($this->hash, $part1, $part2, true);
}
/**
* Mix 2 parts together using another different method
*
* @param string $part1 The first part to mix
* @param string $part2 The second part to mix
*
* @return string The mixed data
*/
protected function mixParts2($part1, $part2)
{
return hash_hmac($this->hash, $part2, $part1, true);
}
}

View File

@@ -0,0 +1,59 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* mcrypt mixer using the Rijndael cipher with 128 bit block size
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2013 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Mixer;
use RandomLib\AbstractMcryptMixer;
use SecurityLib\Strength;
/**
* mcrypt mixer using the Rijndael cipher with 128 bit block size
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Chris Smith <chris@cs278.org>
*/
class McryptRijndael128 extends AbstractMcryptMixer
{
/**
* {@inheritdoc}
*/
public static function getStrength()
{
return new Strength(Strength::HIGH);
}
/**
* {@inheritdoc}
*/
protected function getCipher()
{
return 'rijndael-128';
}
}

View File

@@ -0,0 +1,105 @@
<?php
namespace RandomLib\Mixer;
use RandomLib\AbstractMixer;
use SecurityLib\Strength;
use SecurityLib\Util;
/**
* Class SodiumMixer
*
* @package RandomLib\Mixer
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
*
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @copyright 2017 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
class SodiumMixer extends AbstractMixer
{
const SALSA20_BLOCK_SIZE = 64;
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
return new Strength(Strength::HIGH);
}
/**
* Test to see if the mixer is available
*
* @return bool If the mixer is available on the system
*/
public static function test()
{
return is_callable('sodium_crypto_stream') && is_callable('sodium_crypto_generichash');
}
/**
* @return bool
*/
public static function advisable()
{
return static::test() && !defined('HHVM_VERSION');
}
/**
* Get the block size (the size of the individual blocks used for the mixing)
*
* @return int The block size
*/
protected function getPartSize()
{
return self::SALSA20_BLOCK_SIZE;
}
/**
* Mix 2 parts together using one method
*
* This method is jut a simple BLAKE2b hash of the two strings
* concatenated together
*
* @param string $part1 The first part to mix
* @param string $part2 The second part to mix
*
* @return string The mixed data
*/
protected function mixParts1($part1, $part2)
{
return (string) \sodium_crypto_generichash($part1 . $part2, '', $this->getPartSize());
}
/**
* Mix 2 parts together using another different method
*
* This method is a salsa20 stream based on a hash of the two inputs
*
* @param string $part1 The first part to mix
* @param string $part2 The second part to mix
*
* @return string The mixed data
*/
protected function mixParts2($part1, $part2)
{
// Pre-hash the two inputs into a 448-bit output
/** @var string $hash */
$hash = \sodium_crypto_generichash($part1 . $part2, '', 56);
// Use salsa20 to expand into a pseudorandom string
return (string) \sodium_crypto_stream(
$this->getPartSize(),
Util::safeSubstr($hash, 0, 24),
Util::safeSubstr($hash, 0, 32)
);
}
}

View File

@@ -0,0 +1,111 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Hash medium strength mixer class
*
* This class implements a mixer based upon the recommendations in RFC 4086
* section 5.2
*
* PHP version 5.3
*
* @see http://tools.ietf.org/html/rfc4086#section-5.2
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Mixer;
use SecurityLib\Strength;
/**
* The Hash medium strength mixer class
*
* This class implements a mixer based upon the recommendations in RFC 4086
* section 5.2
*
* @see http://tools.ietf.org/html/rfc4086#section-5.2
*
* @category PHPCryptLib
* @package Random
* @subpackage Mixer
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
*/
class XorMixer extends \RandomLib\AbstractMixer
{
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
return new Strength(Strength::VERYLOW);
}
/**
* Test to see if the mixer is available
*
* @return bool If the mixer is available on the system
*/
public static function test()
{
return true;
}
/**
* Get the block size (the size of the individual blocks used for the mixing)
*
* @return int The block size
*/
protected function getPartSize()
{
return 64;
}
/**
* Mix 2 parts together using one method
*
* @param string $part1 The first part to mix
* @param string $part2 The second part to mix
*
* @return string The mixed data
*/
protected function mixParts1($part1, $part2)
{
return (string) ($part1 ^ $part2);
}
/**
* Mix 2 parts together using another different method
*
* @param string $part1 The first part to mix
* @param string $part2 The second part to mix
*
* @return string The mixed data
*/
protected function mixParts2($part1, $part2)
{
// Both mixers are identical, this is for speed, not security
return (string) ($part1 ^ $part2);
}
}

View File

@@ -0,0 +1,70 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Random Number Source interface.
*
* All random number sources must implement this interface
*
* PHP version 5.3
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib;
/**
* The Random Number Source interface.
*
* All random number sources must implement this interface
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @codeCoverageIgnore
*/
interface Source
{
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength();
/**
* If the source is currently available.
* Reasons might be because the library is not installed
*
* @return bool
*/
public static function isSupported();
/**
* Generate a random string of the specified size
*
* Note: If the source fails to generate enough data, the result must be
* padded to the requested length.
*
* @param int $size The size of the requested random string
*
* @return string A string of the requested size
*/
public function generate($size);
}

View File

@@ -0,0 +1,104 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Capicom Random Number Source
*
* This uses the Windows CapiCom Com object to generate random numbers
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
/**
* The Capicom Random Number Source
*
* This uses the Windows CapiCom Com object to generate random numbers
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @codeCoverageIgnore
*/
class CAPICOM extends \RandomLib\AbstractSource
{
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
return new Strength(Strength::MEDIUM);
}
/**
* If the source is currently available.
* Reasons might be because the library is not installed
*
* @return bool
*/
public static function isSupported()
{
return class_exists('\\COM', false);
}
/**
* Generate a random string of the specified size
*
* @param int $size The size of the requested random string
*
* @return string A string of the requested size
*/
public function generate($size)
{
if (!\class_exists('COM', false)) {
/** @var string $result */
$result = static::emptyValue($size);
return $result;
}
try {
/** @var \COM $util */
$util = new \COM('CAPICOM.Utilities.1');
if (!\method_exists($util, 'GetRandom')) {
/** @var string $result */
$result = static::emptyValue($size);
return $result;
}
$data = base64_decode((string) $util->GetRandom($size, 0));
return (string) str_pad($data, $size, chr(0));
} catch (\Exception $e) {
unset($e);
/** @var string $result */
$result = static::emptyValue($size);
return $result;
}
}
}

View File

@@ -0,0 +1,85 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The MTRand Random Number Source
*
* This source generates low strength random numbers by using the internal
* mt_rand() function. By itself it is quite weak. However when combined with
* other sources it does provide significant benefit.
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
/**
* The MTRand Random Number Source
*
* This source generates low strength random numbers by using the internal
* mt_rand() function. By itself it is quite weak. However when combined with
* other sources it does provide significant benefit.
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @codeCoverageIgnore
*/
class MTRand extends \RandomLib\AbstractSource
{
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
// Detect if Suhosin Hardened PHP patch is applied
if (defined('S_ALL')) {
return new Strength(Strength::LOW);
} else {
return new Strength(Strength::VERYLOW);
}
}
/**
* Generate a random string of the specified size
*
* @param int $size The size of the requested random string
*
* @return string A string of the requested size
*/
public function generate($size)
{
$result = '';
for ($i = 0; $i < $size; $i++) {
$result .= chr((mt_rand() ^ mt_rand()) % 256);
}
return $result;
}
}

View File

@@ -0,0 +1,141 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Microtime Random Number Source
*
* This uses the current micro-second (looped several times) for a **very** weak
* random number source. This is only useful when combined with several other
* stronger sources
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Util;
/**
* The Microtime Random Number Source
*
* This uses the current micro-second (looped several times) for a **very** weak
* random number source. This is only useful when combined with several other
* stronger sources
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @codeCoverageIgnore
*/
final class MicroTime extends \RandomLib\AbstractSource
{
/**
* A static counter to ensure unique hashes and prevent state collisions
*
* @var int A counter
*/
private static $counter = null;
/**
* The current state of the random number generator.
*
* @var string The state of the PRNG
*/
private static $state = '';
public function __construct()
{
$state = self::$state;
if (function_exists('posix_times')) {
$state .= serialize(posix_times());
}
if (!defined('HHVM_VERSION') && function_exists('zend_thread_id')) {
$state .= zend_thread_id();
}
if (function_exists('hphp_get_thread_id')) {
$state .= hphp_get_thread_id();
}
$state .= getmypid() . memory_get_usage();
$state .= serialize($_ENV);
$state .= serialize($_SERVER);
$state .= count(debug_backtrace(false));
self::$state = hash('sha512', $state, true);
if (is_null(self::$counter)) {
list(, self::$counter) = unpack("i", Util::safeSubstr(self::$state, 0, 4));
$seed = $this->generate(Util::safeStrlen(dechex(PHP_INT_MAX)));
list(, self::$counter) = unpack("i", $seed);
}
}
/**
* Generate a random string of the specified size
*
* @param int $size The size of the requested random string
*
* @return string A string of the requested size
*/
public function generate($size)
{
$result = '';
/** @var string $seed */
$seed = (string) \microtime() . \memory_get_usage();
self::$state = hash('sha512', self::$state . $seed, true);
/**
* Make the generated randomness a bit better by forcing a GC run which
* should complete in a indeterminate amount of time, hence improving
* the strength of the randomness a bit. It's still not crypto-safe,
* but at least it's more difficult to predict.
*/
gc_collect_cycles();
for ($i = 0; $i < $size; $i += 8) {
$seed = self::$state .
(string) \microtime() .
(string) \pack('Ni', $i, self::counter());
self::$state = \hash('sha512', $seed, true);
/**
* We only use the first 8 bytes here to prevent exposing the state
* in its entirety, which could potentially expose other random
* generations in the future (in the same process)...
*/
$result .= Util::safeSubstr(self::$state, 0, 8);
}
return Util::safeSubstr($result, 0, $size);
}
/**
* @return int
*/
private static function counter()
{
if (self::$counter >= PHP_INT_MAX) {
self::$counter = -1 * PHP_INT_MAX - 1;
} else {
self::$counter++;
}
return self::$counter;
}
}

View File

@@ -0,0 +1,123 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The OpenSSL Random Number Source
*
* This uses the OS's secure generator to generate high strength numbers
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
/**
* The OpenSSL Random Number Source
*
* This uses the OS's secure generator to generate high strength numbers
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @codeCoverageIgnore
*/
class OpenSSL extends \RandomLib\AbstractSource
{
/**
* Return an instance of Strength indicating the strength of the source
*
* PIE notes: Userland PRNGs are not high strength. OpenSSL is, at best, medium.
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
/**
* Prior to PHP 5.6.12 (see https://bugs.php.net/bug.php?id=70014) the "openssl_random_pseudo_bytes"
* was using "RAND_pseudo_bytes" (predictable) instead of "RAND_bytes" (unpredictable).
* Release notes: http://php.net/ChangeLog-5.php#5.6.12
*/
if (PHP_VERSION_ID >= 50612) {
return new Strength(Strength::MEDIUM);
}
/**
* Prior to PHP 5.5.28 (see https://bugs.php.net/bug.php?id=70014) the "openssl_random_pseudo_bytes"
* was using "RAND_pseudo_bytes" (predictable) instead of "RAND_bytes" (unpredictable).
* Release notes: http://php.net/ChangeLog-5.php#5.5.28
*/
if (PHP_VERSION_ID >= 50528 && PHP_VERSION_ID < 50600) {
return new Strength(Strength::MEDIUM);
}
/**
* Prior to PHP 5.4.44 (see https://bugs.php.net/bug.php?id=70014) the "openssl_random_pseudo_bytes"
* was using "RAND_pseudo_bytes" (predictable) instead of "RAND_bytes" (unpredictable).
* Release notes: http://php.net/ChangeLog-5.php#5.4.44
*/
if (PHP_VERSION_ID >= 50444 && PHP_VERSION_ID < 50500) {
return new Strength(Strength::MEDIUM);
}
return new Strength(Strength::LOW);
}
/**
* If the source is currently available.
* Reasons might be because the library is not installed
*
* @return bool
*/
public static function isSupported()
{
return \is_callable('openssl_random_pseudo_bytes');
}
/**
* Generate a random string of the specified size
*
* @param int $size The size of the requested random string
*
* @return string A string of the requested size
*/
public function generate($size)
{
if ($size < 1) {
return str_repeat(chr(0), $size);
}
/**
* PIE notes: This $crypto_string argument doesn't do what people think
* it does. Original comment follows.
*
* Note, normally we would check the return of of $crypto_strong to
* ensure that we generated a good random string. However, since we're
* using this as one part of many sources a low strength random number
* shouldn't be much of an issue.
*/
return openssl_random_pseudo_bytes($size);
}
}

View File

@@ -0,0 +1,83 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Rand Random Number Source
*
* This source generates low strength random numbers by using the internal
* rand() function. By itself it is quite weak. However when combined with
* other sources it does provide significant benefit.
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
/**
* The Rand Random Number Source
*
* This source generates low strength random numbers by using the internal
* rand() function. By itself it is quite weak. However when combined with
* other sources it does provide significant benefit.
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @codeCoverageIgnore
*/
class Rand extends \RandomLib\AbstractSource
{
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
// Detect if Suhosin Hardened PHP patch is applied
if (defined('S_ALL')) {
return new Strength(Strength::LOW);
} else {
return new Strength(Strength::VERYLOW);
}
}
/**
* Generate a random string of the specified size
*
* @param int $size The size of the requested random string
*
* @return string A string of the requested size
*/
public function generate($size)
{
$result = '';
for ($i = 0; $i < $size; $i++) {
$result .= chr((rand() ^ rand()) % 256);
}
return $result;
}
}

View File

@@ -0,0 +1,85 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The PHP7 Random Number Source
*
* This uses the inbuilt PHP7 Random Bytes function
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
/**
* The PHP7 Random Number Source
*
* This uses the php7 secure generator to generate high strength numbers
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
*/
class RandomBytes extends \RandomLib\AbstractSource
{
/**
* If the source is currently available.
* Reasons might be because the library is not installed
*
* @return bool
*/
public static function isSupported()
{
return \is_callable('random_bytes');
}
/**
* Return an instance of Strength indicating the strength of the source
*
* @return Strength An instance of one of the strength classes
*/
public static function getStrength()
{
return new Strength(Strength::HIGH);
}
/**
* Generate a random string of the specified size
*
* @param int $size The size of the requested random string
*
* @return string A string of the requested size
*/
public function generate($size)
{
if (!self::isSupported()) {
return \str_repeat(chr(0), $size);
}
return \random_bytes($size);
}
}

View File

@@ -0,0 +1,111 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The libsodium Random Number Source
*
* This uses the libsodium secure generator to generate high strength numbers
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Ben Ramsey <ben@benramsey.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*
* @link https://paragonie.com/book/pecl-libsodium
* @link http://pecl.php.net/package/libsodium
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
/**
* The libsodium Random Number Source
*
* This uses the libsodium secure generator to generate high strength numbers
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Ben Ramsey <ben@benramsey.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
*/
class Sodium extends \RandomLib\AbstractSource
{
/**
* A property that may be forcibly set to `false` in the constructor, for
* the purpose of testing this source
*
* @var bool
*/
private $hasLibsodium = false;
/**
* Constructs a libsodium Random Number Source
*
* @param bool $useLibsodium May be set to `false` to disable libsodium for
* testing purposes
*/
public function __construct($useLibsodium = true)
{
if ($useLibsodium && extension_loaded('libsodium')) {
$this->hasLibsodium = true;
}
}
/**
* If the source is currently available.
* Reasons might be because the library is not installed
*
* @return bool
*/
public static function isSupported()
{
return function_exists('Sodium\\randombytes_buf');
}
/**
* Return an instance of Strength indicating the strength of the source
*
* @return Strength An instance of one of the strength classes
*/
public static function getStrength()
{
return new Strength(Strength::HIGH);
}
/**
* Generate a random string of the specified size
*
* @param int $size The size of the requested random string
*
* @return string A string of the requested size
*/
public function generate($size)
{
if (!$this->hasLibsodium || $size < 1) {
return str_repeat(chr(0), $size);
}
return (string) \Sodium\randombytes_buf($size);
}
}

View File

@@ -0,0 +1,108 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The URandom Random Number Source
*
* This uses the *nix /dev/urandom device to generate medium strength numbers
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
/**
* The URandom Random Number Source
*
* This uses the *nix /dev/urandom device to generate medium strength numbers
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @author Paragon Initiative Enterprises <security@paragonie.com>
* @codeCoverageIgnore
*/
class URandom extends \RandomLib\AbstractSource
{
/**
* @var string The file to read from
*/
protected static $file = '/dev/urandom';
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
return new Strength(Strength::HIGH);
}
/**
* If the source is currently available.
* Reasons might be because the library is not installed
*
* @return bool
*/
public static function isSupported()
{
return (bool) @\file_exists(static::$file);
}
/**
* Generate a random string of the specified size
*
* @param int $size The size of the requested random string
*
* @return string A string of the requested size
*/
public function generate($size)
{
if ($size == 0) {
return static::emptyValue($size);
}
$file = \fopen(static::$file, 'rb');
if (!\is_resource($file)) {
/** @var string $result */
$result = static::emptyValue($size);
return $result;
}
if (\is_callable('stream_set_read_buffer')) {
\stream_set_read_buffer($file, 0);
}
/** @var string $result */
$result = \fread($file, $size);
if (!\is_string($result)) {
/** @var string $result */
$result = static::emptyValue($size);
return $result;
}
\fclose($file);
return $result;
}
}

View File

@@ -0,0 +1,77 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The UniqID Random Number Source
*
* This uses the internal `uniqid()` function to generate low strength random
* numbers.
*
* PHP version 5.3
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
*
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
use SecurityLib\Util;
/**
* The UniqID Random Number Source
*
* This uses the internal `uniqid()` function to generate low strength random
* numbers.
*
* @category PHPCryptLib
* @package Random
* @subpackage Source
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @codeCoverageIgnore
*/
class UniqID extends \RandomLib\AbstractSource
{
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
return new Strength(Strength::LOW);
}
/**
* Generate a random string of the specified size
*
* @param int $size The size of the requested random string
*
* @return string A string of the requested size
*/
public function generate($size)
{
$result = '';
while (Util::safeStrlen($result) < $size) {
$result = uniqid($result, true);
}
return Util::safeSubstr($result, 0, $size);
}
}

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="true"
backupStaticAttributes="false"
bootstrap="test/bootstrap.php"
colors="false"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
forceCoversAnnotation="false"
mapTestClassNameToCoveredClassName="false"
processIsolation="false"
stopOnError="false"
stopOnFailure="false"
stopOnIncomplete="false"
stopOnSkipped="false"
testSuiteLoaderClass="PHPUnit_Runner_StandardTestSuiteLoader"
strict="false"
verbose="false">
<testsuites>
<testsuite name="Unit">
<directory>test/Unit</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">lib/</directory>
</whitelist>
</filter>
</phpunit>

29
vendor/paragonie/random-lib/psalm.xml vendored Normal file
View File

@@ -0,0 +1,29 @@
<?xml version="1.0"?>
<psalm
name="Example Psalm config with recommended defaults"
stopOnFirstError="false"
useDocblockTypes="true"
totallyTyped="true"
>
<projectFiles>
<directory name="lib" />
</projectFiles>
<!--
<issueHandlers>
<LessSpecificReturnType errorLevel="info" />
<DeprecatedMethod errorLevel="info" />
<MissingClosureReturnType errorLevel="info" />
<MissingReturnType errorLevel="info" />
<MissingPropertyType errorLevel="info" />
<InvalidDocblock errorLevel="info" />
<MisplacedRequiredParam errorLevel="info" />
<PropertyNotSetInConstructor errorLevel="info" />
<MissingConstructor errorLevel="info" />
<UntypedParam errorLevel="info" />
</issueHandlers>
-->
</psalm>

View File

@@ -0,0 +1,56 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The interface that all hash implementations must implement
*
* PHP version 5.3
*
* @category PHPPasswordLib
* @package Hash
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @license http://www.gnu.org/licenses/lgpl-2.1.html LGPL v 2.1
*/
namespace RandomLibtest\Mocks;
/**
* The interface that all hash implementations must implement
*
* @category PHPPasswordLib
* @package Hash
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
*/
class AbstractMock
{
protected $callbacks = array();
public static function init()
{
}
public function __construct(array $callbacks = array())
{
$this->callbacks = $callbacks;
}
public function __call($name, array $args = array())
{
if (isset($this->callbacks[$name])) {
return call_user_func_array($this->callbacks[$name], $args);
}
return null;
}
}

View File

@@ -0,0 +1,80 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Mixer strategy interface.
*
* All mixing strategies must implement this interface
*
* PHP version 5.3
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @license http://www.gnu.org/licenses/lgpl-2.1.html LGPL v 2.1
*/
namespace RandomLibtest\Mocks\Random;
/**
* The Mixer strategy interface.
*
* All mixing strategies must implement this interface
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
*/
class Generator extends \RandomLib\Generator
{
protected $callbacks = array();
public static function init()
{
}
public function __construct(array $callbacks = array())
{
$this->callbacks = $callbacks;
}
public function __call($name, array $args = array())
{
if (isset($this->callbacks[$name])) {
return call_user_func_array($this->callbacks[$name], $args);
}
return null;
}
public function addSource(\PasswordLib\Random\Source $source)
{
return $this->__call('addSource', array($source));
}
public function generate($size)
{
return $this->__call('generate', array($size));
}
public function generateInt($min = 0, $max = \PHP_INT_MAX)
{
return $this->__call('generateInt', array($min, $max));
}
public function generateString($length, $chars = '')
{
return $this->__call('generateString', array($length, $chars));
}
}

View File

@@ -0,0 +1,86 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Mixer strategy interface.
*
* All mixing strategies must implement this interface
*
* PHP version 5.3
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @license http://www.gnu.org/licenses/lgpl-2.1.html LGPL v 2.1
*/
namespace RandomLibtest\Mocks\Random;
use SecurityLib\Strength;
/**
* The Mixer strategy interface.
*
* All mixing strategies must implement this interface
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
*/
class Mixer extends \RandomLibTest\Mocks\AbstractMock implements \RandomLib\Mixer
{
public static $strength = null;
public static $test = true;
public static function init()
{
static::$strength = new Strength(Strength::HIGH);
static::$test = true;
}
/**
* Return an instance of Strength indicating the strength of the mixer
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
return static::$strength;
}
/**
* Test to see if the mixer is available
*
* @return bool If the mixer is available on the system
*/
public static function test()
{
return static::$test;
}
/**
* Mix the provided array of strings into a single output of the same size
*
* All elements of the array should be the same size.
*
* @param array $parts The parts to be mixed
*
* @return string The mixed result
*/
public function mix(array $parts)
{
return $this->__call('mix', array($parts));
}
}

View File

@@ -0,0 +1,85 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* The Random Number Source interface.
*
* All random number sources must implement this interface
*
* PHP version 5.3
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @license http://www.gnu.org/licenses/lgpl-2.1.html LGPL v 2.1
*/
namespace RandomLibtest\Mocks\Random;
use SecurityLib\Strength;
/**
* The Random Number Source interface.
*
* All random number sources must implement this interface
*
* @category PHPPasswordLib
* @package Random
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
*/
class Source extends \RandomLibTest\Mocks\AbstractMock implements \RandomLib\Source
{
public static $strength = null;
public static function init()
{
static::$strength = new Strength(Strength::VERYLOW);
}
/**
* Return an instance of Strength indicating the strength of the source
*
* @return \SecurityLib\Strength An instance of one of the strength classes
*/
public static function getStrength()
{
return static::$strength;
}
/**
* If the source is currently available.
* Reasons might be because the library is not installed
*
* @return bool
*/
public static function isSupported()
{
return true;
}
/**
* Generate a random string of the specified size
*
* Note: If the source fails to generate enough data, the result must be
* padded to the requested length.
*
* @param int $size The size of the requested random string
*
* @return string A string of the requested size
*/
public function generate($size)
{
return $this->__call('generate', array($size));
}
}

View File

@@ -0,0 +1,68 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
namespace RandomLib;
use SecurityLib\Strength;
class FactoryTest extends \PHPUnit_Framework_TestCase
{
public function testConstruct()
{
$factory = new Factory();
$this->assertTrue($factory instanceof Factory);
}
public function testGetGeneratorFallback()
{
$factory = new Factory();
$generator = $factory->getGenerator(new Strength(Strength::VERYLOW));
$mixer = call_user_func(array(
get_class($generator->getMixer()),
'getStrength',
));
$this->assertTrue($mixer->compare(new Strength(Strength::VERYLOW)) <= 0);
}
/**
* @covers RandomLib\Factory::getMediumStrengthGenerator
* @covers RandomLib\Factory::getGenerator
* @covers RandomLib\Factory::findMixer
* @covers RandomLib\Factory::findSources
*/
public function testGetMediumStrengthGenerator()
{
$factory = new Factory();
$generator = $factory->getMediumStrengthGenerator();
$this->assertTrue($generator instanceof Generator);
$mixer = call_user_func(array(
get_class($generator->getMixer()),
'getStrength',
));
$this->assertTrue($mixer->compare(new Strength(Strength::MEDIUM)) <= 0);
foreach ($generator->getSources() as $source) {
$strength = call_user_func(array(get_class($source), 'getStrength'));
$this->assertTrue($strength->compare(new Strength(Strength::MEDIUM)) >= 0);
}
}
/**
* @expectedException RuntimeException
* @expectedExceptionMessage Could not find sources
*/
public function testNoAvailableSource()
{
$factory = new Factory();
$sources = new \ReflectionProperty($factory, 'sources');
$sources->setAccessible(true);
$sources->setValue($factory, array());
$factory->getMediumStrengthGenerator();
}
}

View File

@@ -0,0 +1,111 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
namespace RandomLib;
class GeneratorStringTest extends \PHPUnit_Framework_TestCase
{
/**
* @var Generator
*/
protected $generator = null;
/**
* @var Mixer
*/
protected $mixer = null;
/**
* @var array<int, Source>
*/
protected $sources = array();
public static function provideCharCombinations()
{
return array(
array("CHAR_LOWER", implode("", range("a", "z"))),
array("CHAR_UPPER", implode("", range("A", "Z"))),
array("CHAR_DIGITS", implode("", range(0, 9))),
array("CHAR_UPPER_HEX", "0123456789ABCDEF"),
array("CHAR_LOWER_HEX", "0123456789abcdef"),
array("CHAR_BASE64", "+/0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"),
array("EASY_TO_READ", "3479ACEFHJKLMNPRTUVWXYabcdefghijkmnopqrstuvwxyz"),
array("CHAR_BRACKETS", "()<>[]{}"),
array("CHAR_SYMBOLS", " !\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~"),
array("CHAR_PUNCT", ",.:;"),
array("CHAR_ALPHA", implode("", array_merge(range("A", "Z"), range("a", "z")))),
array("CHAR_ALNUM", implode("", array_merge(range(0, 9), range("A", "Z"), range("a", "z")))),
array("CHAR_ALPHA | PUNCT", ",.:;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", Generator::CHAR_ALPHA | Generator::CHAR_PUNCT),
array("CHAR_LOWER | EASY_TO_READ", "abcdefghijkmnopqrstuvwxyz", Generator::CHAR_LOWER | Generator::EASY_TO_READ),
array("CHAR_DIGITS | EASY_TO_READ", "3479", Generator::CHAR_DIGITS | Generator::EASY_TO_READ),
);
}
public function setUp()
{
$source1 = $this->getMock('RandomLib\Source');
$source1->expects($this->any())
->method('generate')
->will($this->returnCallback(function ($size) {
$r = '';
for ($i = 0; $i < $size; $i++) {
$r .= chr($i % 256);
}
return $r;
}
));
$source2 = $this->getMock('RandomLib\Source');
$source2->expects($this->any())
->method('generate')
->will($this->returnCallback(function ($size) {
$r = '';
for ($i = 0; $i < $size; $i++) {
$r .= chr(0);
}
return $r;
}
));
$this->mixer = $this->getMock('RandomLib\Mixer');
$this->mixer->expects($this->any())
->method('mix')
->will($this->returnCallback(function (array $sources) {
if (empty($sources)) {
return '';
}
$start = array_pop($sources);
// throw new \Exception('test');
return array_reduce(
$sources,
function ($el1, $el2) {
return $el1 ^ $el2;
},
$start
);
}));
$this->sources = array($source1, $source2);
$this->generator = new Generator($this->sources, $this->mixer);
}
/**
* @dataProvider provideCharCombinations
*/
public function testScheme($schemeName, $expected, $scheme = 0)
{
// test for overspecification by doubling the expected amount
if (!$scheme) {
$scheme = constant("RandomLib\Generator::$schemeName");
}
$chars = $this->generator->generateString(strlen($expected) * 2, $scheme);
$this->assertEquals($expected . $expected, $chars, sprintf("Testing Generator::%s failed", $schemeName));
}
}

View File

@@ -0,0 +1,202 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
namespace RandomLib;
class GeneratorTest extends \PHPUnit_Framework_TestCase
{
protected $generator = null;
protected $mixer = null;
protected $sources = array();
public static function provideGenerate()
{
return array(
array(0, ''),
array(1, chr(0)),
array(2, chr(1) . chr(1)),
array(3, chr(2) . chr(0) . chr(2)),
array(4, chr(3) . chr(3) . chr(3) . chr(3)),
);
}
public static function provideGenerateInt()
{
return array(
array(1, 1, 1),
array(0, 1, 0),
array(0, 255, 0),
array(400, 655, 400),
array(0, 65535, 257),
array(65535, 131070, 65792),
array(0, 16777215, (2<<16) + 2),
array(-10, 0, -10),
array(-655, -400, -655),
array(-131070, -65535, -130813),
);
}
public static function provideGenerateIntRangeTest()
{
return array(
array(0, 0),
array(0, 1),
array(1, 10000),
array(100000, \PHP_INT_MAX),
);
}
public static function provideGenerateStringTest()
{
return array(
array(0, 'ab', ''),
array(1, 'ab', 'a'),
array(1, 'a', ''),
array(2, 'ab', 'bb'),
array(3, 'abc', 'cac'),
array(8, '0123456789abcdef', '77777777'),
array(16, '0123456789abcdef', 'ffffffffffffffff'),
array(16, '', 'DDDDDDDDDDDDDDDD'),
);
}
public function setUp()
{
$source1 = $this->getMock('RandomLib\Source');
$source1->expects($this->any())
->method('generate')
->will($this->returnCallback(function ($size) {
$r = '';
for ($i = 0; $i < $size; $i++) {
$r .= chr($i);
}
return $r;
}
));
$source2 = $this->getMock('RandomLib\Source');
$source2->expects($this->any())
->method('generate')
->will($this->returnCallback(function ($size) {
$r = '';
for ($i = $size - 1; $i >= 0; $i--) {
$r .= chr($i);
}
return $r;
}
));
$this->mixer = $this->getMock('RandomLib\Mixer');
$this->mixer->expects($this->any())
->method('mix')
->will($this->returnCallback(function (array $sources) {
if (empty($sources)) {
return '';
}
$start = array_pop($sources);
return array_reduce(
$sources,
function ($el1, $el2) {
return $el1 ^ $el2;
},
$start
);
}));
$this->sources = array($source1, $source2);
$this->generator = new Generator($this->sources, $this->mixer);
}
public function testConstruct()
{
$this->assertTrue($this->generator instanceof Generator);
}
public function testGetMixer()
{
$this->assertSame($this->mixer, $this->generator->getMixer());
}
public function testGetSources()
{
$this->assertSame($this->sources, $this->generator->getSources());
}
/**
* @dataProvider provideGenerate
*/
public function testGenerate($size, $expect)
{
$this->assertEquals($expect, $this->generator->generate($size));
}
/**
* @dataProvider provideGenerateInt
*/
public function testGenerateInt($min, $max, $expect)
{
$this->assertEquals($expect, $this->generator->generateInt($min, $max));
}
/**
* @dataProvider provideGenerateIntRangeTest
*/
public function testGenerateIntRange($min, $max)
{
$n = $this->generator->generateInt($min, $max);
$this->assertTrue($min <= $n);
$this->assertTrue($max >= $n);
}
/**
* @expectedException RangeException
*/
public function testGenerateIntFail()
{
$n = $this->generator->generateInt(-1, PHP_INT_MAX);
}
public function testGenerateIntLargeTest()
{
$bits = 30;
$expected = 50529027;
if (PHP_INT_MAX > 4000000000) {
$bits = 55;
$expected = 1693273676973062;
}
$n = $this->generator->generateInt(0, (int) pow(2, $bits));
$this->assertEquals($expected, $n);
}
/**
* @dataProvider provideGenerateStringTest
*/
public function testGenerateString($length, $chars, $expected)
{
$n = $this->generator->generateString($length, $chars);
$this->assertEquals($expected, $n);
}
/**
* This test checks for issue #22:
*
* @see https://github.com/ircmaxell/RandomLib/issues/22
*/
public function testGenerateLargeRange()
{
if (PHP_INT_MAX < pow(2, 32)) {
$this->markTestSkipped("Only test on 64 bit platforms");
}
$this->assertEquals(506381209866536711, $this->generator->generateInt(0, PHP_INT_MAX));
}
}

View File

@@ -0,0 +1,63 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
namespace RandomLib\Mixer;
use SecurityLib\Strength;
class HashTest extends \PHPUnit_Framework_TestCase
{
public static function provideMix()
{
$data = array(
array(array(), ''),
array(array('1', '1'), '0d'),
array(array('a'), '61'),
// This expects 'b' because of how the mock hmac function works
array(array('a', 'b'), '9a'),
array(array('aa', 'ba'), '6e84'),
array(array('ab', 'bb'), 'b0cb'),
array(array('aa', 'bb'), 'ae8d'),
array(array('aa', 'bb', 'cc'), 'a14c'),
array(array('aabbcc', 'bbccdd', 'ccddee'), 'a8aff3939934'),
);
return $data;
}
public function testConstructWithoutArgument()
{
$hash = new Hash();
$this->assertTrue($hash instanceof \RandomLib\Mixer);
}
public function testGetStrength()
{
$strength = new Strength(Strength::MEDIUM);
$actual = Hash::getStrength();
$this->assertEquals($actual, $strength);
}
public function testTest()
{
$actual = Hash::test();
$this->assertTrue($actual);
}
/**
* @dataProvider provideMix
*/
public function testMix($parts, $result)
{
$mixer = new Hash('md5');
$actual = $mixer->mix($parts);
$this->assertEquals($result, bin2hex($actual));
}
}

View File

@@ -0,0 +1,69 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
namespace RandomLib\Mixer;
use SecurityLib\Strength;
class McryptRijndael128Test extends \PHPUnit_Framework_TestCase
{
public static function provideMix()
{
$data = array(
array(array(), ''),
array(array('', ''), ''),
array(array('a'), '61'),
array(array('a', 'b'), '6a'),
array(array('aa', 'ba'), '688d'),
array(array('ab', 'bb'), 'f8bc'),
array(array('aa', 'bb'), 'a0f3'),
array(array('aa', 'bb', 'cc'), '87c3'),
array(array('aabbcc', 'bbccdd', 'ccddee'), '7cf2273e46c7'),
);
return $data;
}
protected function setUp()
{
if (!\extension_loaded('mcrypt') || PHP_VERSION_ID >= 70100) {
$this->markTestSkipped('mcrypt extension is not available');
}
}
public function testConstructWithoutArgument()
{
$hash = new McryptRijndael128();
$this->assertTrue($hash instanceof \RandomLib\Mixer);
}
public function testGetStrength()
{
$strength = new Strength(Strength::HIGH);
$actual = McryptRijndael128::getStrength();
$this->assertEquals($actual, $strength);
}
public function testTest()
{
$actual = McryptRijndael128::test();
$this->assertTrue($actual);
}
/**
* @dataProvider provideMix
*/
public function testMix($parts, $result)
{
$mixer = new McryptRijndael128();
$actual = $mixer->mix($parts);
$this->assertEquals($result, bin2hex($actual));
}
}

View File

@@ -0,0 +1,69 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
namespace RandomLib\Mixer;
use SecurityLib\Strength;
class SodiumTest extends \PHPUnit_Framework_TestCase
{
public static function provideMix()
{
$data = array(
array(array(), ''),
array(array('', ''), ''),
array(array('a'), '61'),
array(array('a', 'b'), '44'),
array(array('aa', 'ba'), '6967'),
array(array('ab', 'bb'), '73a6'),
array(array('aa', 'bb'), 'bc7b'),
array(array('aa', 'bb', 'cc'), '0cbd'),
array(array('aabbcc', 'bbccdd', 'ccddee'), '5f0005cacd7c'),
);
return $data;
}
protected function setUp()
{
if (!\is_callable('sodium_crypto_generichash') || defined('HHVM_VERSION')) {
$this->markTestSkipped('sodium extension is not available');
}
}
public function testConstructWithoutArgument()
{
$hash = new SodiumMixer();
$this->assertTrue($hash instanceof \RandomLib\Mixer);
}
public function testGetStrength()
{
$strength = new Strength(Strength::HIGH);
$actual = SodiumMixer::getStrength();
$this->assertEquals($actual, $strength);
}
public function testTest()
{
$actual = SodiumMixer::test();
$this->assertTrue($actual);
}
/**
* @dataProvider provideMix
*/
public function testMix($parts, $result)
{
$mixer = new SodiumMixer();
$actual = $mixer->mix($parts);
$this->assertEquals($result, bin2hex($actual));
}
}

View File

@@ -0,0 +1,67 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
abstract class AbstractSourceTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
$class = static::getTestedClass();
if (!$class::isSupported()) {
$this->markTestSkipped();
}
}
protected static function getTestedClass()
{
return preg_replace('/Test$/', '', get_called_class());
}
protected static function getExpectedStrength()
{
return new Strength(Strength::VERYLOW);
}
public static function provideGenerate()
{
$data = array();
for ($i = 0; $i < 100; $i += 5) {
$not = $i > 0 ? str_repeat(chr(0), $i) : chr(0);
$data[] = array($i, $not);
}
return $data;
}
public function testGetStrength()
{
$class = static::getTestedClass();
$strength = static::getExpectedStrength();
$actual = $class::getStrength();
$this->assertEquals($actual, $strength);
}
/**
* @dataProvider provideGenerate
* @group slow
*/
public function testGenerate($length, $not)
{
$class = static::getTestedClass();
$rand = new $class();
$stub = $rand->generate($length);
$this->assertEquals($length, strlen($stub));
$this->assertNotEquals($not, $stub);
}
}

View File

@@ -0,0 +1,21 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
class CAPICOMTest extends AbstractSourceTest
{
protected static function getExpectedStrength()
{
return new Strength(Strength::MEDIUM);
}
}

View File

@@ -0,0 +1,25 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
class MTRandTest extends AbstractSourceTest
{
protected static function getExpectedStrength()
{
if (defined('S_ALL')) {
return new Strength(Strength::LOW);
} else {
return new Strength(Strength::VERYLOW);
}
}
}

View File

@@ -0,0 +1,33 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
class MicroTimeTest extends AbstractSourceTest
{
protected static function getExpectedStrength()
{
return new Strength(Strength::VERYLOW);
}
/**
* Test the initialization of the static counter (!== 0)
*/
public function testCounterNotNull()
{
$class = static::getTestedClass();
$rand = new $class();
$reflection_class = new \ReflectionClass($class);
$static = $reflection_class->getStaticProperties();
$this->assertTrue($static['counter'] !== 0);
}
}

View File

@@ -0,0 +1,25 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
class RandTest extends AbstractSourceTest
{
protected static function getExpectedStrength()
{
if (defined('S_ALL')) {
return new Strength(Strength::LOW);
} else {
return new Strength(Strength::VERYLOW);
}
}
}

View File

@@ -0,0 +1,88 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
class SodiumTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
if (!extension_loaded('libsodium')) {
$this->markTestSkipped('The libsodium extension is not loaded');
}
}
public static function provideGenerate()
{
$data = array();
for ($i = 1; $i < 100; $i += 5) {
$not = str_repeat(chr(0), $i);
$data[] = array($i, $not);
}
return $data;
}
public function testGetStrength()
{
$strength = new Strength(Strength::HIGH);
$actual = Sodium::getStrength();
$this->assertEquals($actual, $strength);
}
/**
* @dataProvider provideGenerate
*/
public function testGenerate($length, $not)
{
if (!extension_loaded('libsodium')) {
$this->markTestSkipped('The libsodium extension is not loaded');
}
$rand = new Sodium();
$stub = $rand->generate($length);
$this->assertEquals($length, strlen($stub));
$this->assertNotEquals($not, $stub);
}
/**
* @dataProvider provideGenerate
*/
public function testGenerateWithoutLibsodium($length, $not)
{
$rand = new Sodium(false);
$stub = $rand->generate($length);
$this->assertEquals($length, strlen($stub));
$this->assertEquals($not, $stub);
}
public function testGenerateWithZeroLength()
{
if (!extension_loaded('libsodium')) {
$this->markTestSkipped('The libsodium extension is not loaded');
}
$rand = new Sodium();
$stub = $rand->generate(0);
$this->assertEquals(0, strlen($stub));
$this->assertEquals('', $stub);
}
public function testGenerateWithZeroLengthWithoutLibsodium()
{
$rand = new Sodium(false);
$stub = $rand->generate(0);
$this->assertEquals(0, strlen($stub));
$this->assertEquals('', $stub);
}
}

View File

@@ -0,0 +1,21 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
class URandomTest extends AbstractSourceTest
{
protected static function getExpectedStrength()
{
return new Strength(Strength::HIGH);
}
}

View File

@@ -0,0 +1,21 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
namespace RandomLib\Source;
use SecurityLib\Strength;
class UniqIDTest extends AbstractSourceTest
{
protected static function getExpectedStrength()
{
return new Strength(Strength::LOW);
}
}

View File

@@ -0,0 +1,168 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
use RandomLib\Generator;
use RandomLibTest\Mocks\Random\Mixer;
use RandomLibTest\Mocks\Random\Source;
class Vectors_Random_GeneratorTest extends PHPUnit_Framework_TestCase
{
public static function provideGenerateInt()
{
return array(
// First, lets test each offset based range
array(0, 7),
array(0, 15),
array(0, 31),
array(0, 63),
array(0, 127),
array(0, 255),
array(0, 511),
array(0, 1023),
// Let's try a range not starting at 0
array(8, 15),
// Let's try a range with a negative number
array(-18, -11),
// Let's try a non-power-of-2 range
array(10, 100),
// Finally, let's try two large numbers
array(100000, 100007),
array(100000000, 100002047),
// Now, let's force a few loops by setting a valid offset
array(0, 5, 2),
array(0, 9, 5),
array(0, 27, 4),
);
}
public static function provideGenerators()
{
$factory = new \RandomLib\Factory();
$generator = $factory->getLowStrengthGenerator();
$sources = $generator->getSources();
$ret = array();
$ret[] = array(new Generator($sources, new \RandomLib\Mixer\Hash()), 10000, 'hash');
return $ret;
}
/**
* This test asserts that the algorithm that generates the integers does not
* actually introduce any bias into the generated numbers. If this test
* passes, the generated integers from the generator will be as unbiased as
* the sources that provide the data.
*
* @dataProvider provideGenerateInt
*/
public function testGenerateInt($min, $max, $offset = 0)
{
$generator = $this->getGenerator($max - $min + $offset);
for ($i = $max; $i >= $min; $i--) {
$this->assertEquals($i, $generator->generateInt($min, $max));
}
}
/**
* This generator generates two bytes at a time, and uses each 8 bit segment of
* the generated byte as a coordinate on a grid (so 01011010 would be the
* coordinate (0101, 1010) or (5, 10). These are used as inputs to a MonteCarlo
* algorithm for the integral of y=x over a 15x15 grid. The expected answer is
* 1/2 * 15 * 15 (or 1/2 * base * height, since the result is a triangle).
* Therefore, if we get an answer close to that, we know the generator is good.
*
* Now, since the area under the line should be equal to the area above the line.
* Therefore, the ratio of the two areas should be equal. This way, we can avoid
* computing total to figure out the areas.
*
* I have set the bounds on the test to be 80% and 120%. Meaning that I will
* consider the test valid and unbiased if the number of random elements that
* fall under (inside) of the line and the number that fall outside of the line
* are at most 20% apart.
*
* Since testing randomness is not reliable or repeatable, I will only fail the
* test in two different scenarios. The first is if after the iterations the
* outside or the inside is 0. The chances of that happening are so low that
* if it happens, it's relatively safe to assume that something bad happened. The
* second scenario happens when the ratio is outside of the 20% tolerance. If
* that happens, I will re-run the entire test. If that test is outside of the 20%
* tolerance, then the test will fail
*
*
* @dataProvider provideGenerators
*/
public function testGenerate(\RandomLib\Generator $generator, $times)
{
$ratio = $this->doTestGenerate($generator, $times);
if ($ratio < 0.8 || $ratio > 1.2) {
$ratio2 = $this->doTestGenerate($generator, $times);
if ($ratio2 > 1.2 || $ratio2 < 0.8) {
$this->fail(
sprintf(
'The test failed multiple runs with final ratios %f and %f',
$ratio,
$ratio2
)
);
}
}
}
protected function doTestGenerate(\RandomLib\Generator $generator, $times)
{
$inside = 0;
$outside = 0;
$on = 0;
for ($i = 0; $i < $times; $i++) {
$byte = $generator->generate(2);
$byte = unpack('n', $byte);
$byte = array_shift($byte);
$xCoord = ($byte >> 8);
$yCoord = ($byte & 0xFF);
if ($xCoord < $yCoord) {
$outside++;
} elseif ($xCoord == $yCoord) {
$on++;
} else {
$inside++;
}
}
$this->assertGreaterThan(0, $outside, 'Outside Is 0');
$this->assertGreaterThan(0, $inside, 'Inside Is 0');
$ratio = $inside / $outside;
return $ratio;
}
public function getGenerator($random)
{
$source1 = new Source(array(
'generate' => function ($size) use (&$random) {
$ret = pack('N', $random);
$random--;
return substr($ret, -1 * $size);
},
));
$sources = array($source1);
$mixer = new Mixer(array(
'mix'=> function (array $sources) {
if (empty($sources)) {
return '';
}
return array_pop($sources);
},
));
return new Generator($sources, $mixer);
}
}

View File

@@ -0,0 +1,58 @@
<?php
/*
* The RandomLib library for securely generating random numbers and strings in PHP
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version Build @@version@@
*/
/**
* Bootstrap the library. This registers a simple autoloader for autoloading
* classes
*
* If you are using this library inside of another that uses a similar
* autoloading system, you can use that autoloader instead of this file.
*
* PHP version 5.3
*
* @category PHPPasswordLib
* @package test
*
* @author Anthony Ferrara <ircmaxell@ircmaxell.com>
* @copyright 2011 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @license http://www.gnu.org/licenses/lgpl-2.1.html LGPL v 2.1
*/
namespace RandomLibTest;
ini_set('memory_limit', '1G');
/**
* The simple autoloader for the PasswordLibTest libraries.
*
* This does not use the PRS-0 standards due to the namespace prefix and directory
* structure
*
* @param string $class The class name to load
*
* @return void
*/
spl_autoload_register(function ($class) {
$nslen = strlen(__NAMESPACE__);
if (substr($class, 0, $nslen) != __NAMESPACE__) {
//Only autoload libraries from this package
return;
}
$path = substr(str_replace('\\', '/', $class), $nslen);
$path = __DIR__ . $path . '.php';
if (file_exists($path)) {
require $path;
}
});
define('PATH_ROOT', dirname(__DIR__));
require_once dirname(__DIR__) . '/vendor/autoload.php';

22
vendor/paragonie/random_compat/LICENSE vendored Normal file
View File

@@ -0,0 +1,22 @@
The 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.

View File

@@ -0,0 +1,38 @@
{
"name": "paragonie/random_compat",
"description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
"keywords": [
"csprng",
"random",
"polyfill",
"pseudorandom"
],
"license": "MIT",
"type": "library",
"authors": [
{
"name": "Paragon Initiative Enterprises",
"email": "security@paragonie.com",
"homepage": "https://paragonie.com"
}
],
"support": {
"issues": "https://github.com/paragonie/random_compat/issues",
"email": "info@paragonie.com",
"source": "https://github.com/paragonie/random_compat"
},
"require": {
"php": ">=5.2.0"
},
"require-dev": {
"phpunit/phpunit": "*"
},
"suggest": {
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
},
"autoload": {
"files": [
"lib/random.php"
]
}
}

View File

@@ -0,0 +1,5 @@
-----BEGIN PUBLIC KEY-----
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEEd+wCqJDrx5B4OldM0dQE0ZMX+lx1ZWm
pui0SUqD4G29L3NGsz9UhJ/0HjBdbnkhIK5xviT0X5vtjacF6ajgcCArbTB+ds+p
+h7Q084NuSuIpNb6YPfoUFgC/CL9kAoc
-----END PUBLIC KEY-----

View File

@@ -0,0 +1,11 @@
-----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-----

View File

@@ -0,0 +1,195 @@
<?php
/**
* Random_* Compatibility Library
* for using the new PHP 7 random_* API in PHP 5 projects
*
* The MIT License (MIT)
*
* Copyright (c) 2015 - 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.
*/
if (!is_callable('RandomCompat_strlen')) {
if (
defined('MB_OVERLOAD_STRING')
&&
((int) ini_get('mbstring.func_overload')) & MB_OVERLOAD_STRING
) {
/**
* strlen() implementation that isn't brittle to mbstring.func_overload
*
* This version uses mb_strlen() in '8bit' mode to treat strings as raw
* binary rather than UTF-8, ISO-8859-1, etc
*
* @param string $binary_string
*
* @throws TypeError
*
* @return int
*/
function RandomCompat_strlen($binary_string)
{
if (!is_string($binary_string)) {
throw new TypeError(
'RandomCompat_strlen() expects a string'
);
}
return (int) mb_strlen($binary_string, '8bit');
}
} else {
/**
* strlen() implementation that isn't brittle to mbstring.func_overload
*
* This version just used the default strlen()
*
* @param string $binary_string
*
* @throws TypeError
*
* @return int
*/
function RandomCompat_strlen($binary_string)
{
if (!is_string($binary_string)) {
throw new TypeError(
'RandomCompat_strlen() expects a string'
);
}
return (int) strlen($binary_string);
}
}
}
if (!is_callable('RandomCompat_substr')) {
if (
defined('MB_OVERLOAD_STRING')
&&
((int) ini_get('mbstring.func_overload')) & MB_OVERLOAD_STRING
) {
/**
* substr() implementation that isn't brittle to mbstring.func_overload
*
* This version uses mb_substr() in '8bit' mode to treat strings as raw
* binary rather than UTF-8, ISO-8859-1, etc
*
* @param string $binary_string
* @param int $start
* @param int|null $length (optional)
*
* @throws TypeError
*
* @return string
*/
function RandomCompat_substr($binary_string, $start, $length = null)
{
if (!is_string($binary_string)) {
throw new TypeError(
'RandomCompat_substr(): First argument should be a string'
);
}
if (!is_int($start)) {
throw new TypeError(
'RandomCompat_substr(): Second argument should be an integer'
);
}
if ($length === null) {
/**
* mb_substr($str, 0, NULL, '8bit') returns an empty string on
* PHP 5.3, so we have to find the length ourselves.
*/
/** @var int $length */
$length = RandomCompat_strlen($binary_string) - $start;
} elseif (!is_int($length)) {
throw new TypeError(
'RandomCompat_substr(): Third argument should be an integer, or omitted'
);
}
// Consistency with PHP's behavior
if ($start === RandomCompat_strlen($binary_string) && $length === 0) {
return '';
}
if ($start > RandomCompat_strlen($binary_string)) {
return '';
}
return (string) mb_substr(
(string) $binary_string,
(int) $start,
(int) $length,
'8bit'
);
}
} else {
/**
* substr() implementation that isn't brittle to mbstring.func_overload
*
* This version just uses the default substr()
*
* @param string $binary_string
* @param int $start
* @param int|null $length (optional)
*
* @throws TypeError
*
* @return string
*/
function RandomCompat_substr($binary_string, $start, $length = null)
{
if (!is_string($binary_string)) {
throw new TypeError(
'RandomCompat_substr(): First argument should be a string'
);
}
if (!is_int($start)) {
throw new TypeError(
'RandomCompat_substr(): Second argument should be an integer'
);
}
if ($length !== null) {
if (!is_int($length)) {
throw new TypeError(
'RandomCompat_substr(): Third argument should be an integer, or omitted'
);
}
return (string) substr(
(string )$binary_string,
(int) $start,
(int) $length
);
}
return (string) substr(
(string) $binary_string,
(int) $start
);
}
}
}

View File

@@ -0,0 +1,77 @@
<?php
/**
* Random_* Compatibility Library
* for using the new PHP 7 random_* API in PHP 5 projects
*
* The MIT License (MIT)
*
* Copyright (c) 2015 - 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.
*/
if (!is_callable('RandomCompat_intval')) {
/**
* Cast to an integer if we can, safely.
*
* If you pass it a float in the range (~PHP_INT_MAX, PHP_INT_MAX)
* (non-inclusive), it will sanely cast it to an int. If you it's equal to
* ~PHP_INT_MAX or PHP_INT_MAX, we let it fail as not an integer. Floats
* lose precision, so the <= and => operators might accidentally let a float
* through.
*
* @param int|float $number The number we want to convert to an int
* @param bool $fail_open Set to true to not throw an exception
*
* @return float|int
* @psalm-suppress InvalidReturnType
*
* @throws TypeError
*/
function RandomCompat_intval($number, $fail_open = false)
{
if (is_int($number) || is_float($number)) {
$number += 0;
} elseif (is_numeric($number)) {
/** @psalm-suppress InvalidOperand */
$number += 0;
}
/** @var int|float $number */
if (
is_float($number)
&&
$number > ~PHP_INT_MAX
&&
$number < PHP_INT_MAX
) {
$number = (int) $number;
}
if (is_int($number)) {
return (int) $number;
} elseif (!$fail_open) {
throw new TypeError(
'Expected an integer.'
);
}
return $number;
}
}

View File

@@ -0,0 +1,49 @@
<?php
/**
* Random_* Compatibility Library
* for using the new PHP 7 random_* API in PHP 5 projects
*
* The MIT License (MIT)
*
* Copyright (c) 2015 - 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.
*/
if (!class_exists('Error', false)) {
// We can't really avoid making this extend Exception in PHP 5.
class Error extends Exception
{
}
}
if (!class_exists('TypeError', false)) {
if (is_subclass_of('Error', 'Exception')) {
class TypeError extends Error
{
}
} else {
class TypeError extends Exception
{
}
}
}

View File

@@ -0,0 +1,226 @@
<?php
/**
* Random_* Compatibility Library
* for using the new PHP 7 random_* API in PHP 5 projects
*
* @version 2.0.17
* @released 2018-07-04
*
* The MIT License (MIT)
*
* Copyright (c) 2015 - 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.
*/
if (!defined('PHP_VERSION_ID')) {
// This constant was introduced in PHP 5.2.7
$RandomCompatversion = array_map('intval', explode('.', PHP_VERSION));
define(
'PHP_VERSION_ID',
$RandomCompatversion[0] * 10000
+ $RandomCompatversion[1] * 100
+ $RandomCompatversion[2]
);
$RandomCompatversion = null;
}
/**
* PHP 7.0.0 and newer have these functions natively.
*/
if (PHP_VERSION_ID >= 70000) {
return;
}
if (!defined('RANDOM_COMPAT_READ_BUFFER')) {
define('RANDOM_COMPAT_READ_BUFFER', 8);
}
$RandomCompatDIR = dirname(__FILE__);
require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'byte_safe_strings.php';
require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'cast_to_int.php';
require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'error_polyfill.php';
if (!is_callable('random_bytes')) {
/**
* PHP 5.2.0 - 5.6.x way to implement random_bytes()
*
* We use conditional statements here to define the function in accordance
* to the operating environment. It's a micro-optimization.
*
* In order of preference:
* 1. Use libsodium if available.
* 2. fread() /dev/urandom if available (never on Windows)
* 3. mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM)
* 4. COM('CAPICOM.Utilities.1')->GetRandom()
*
* See RATIONALE.md for our reasoning behind this particular order
*/
if (extension_loaded('libsodium')) {
// See random_bytes_libsodium.php
if (PHP_VERSION_ID >= 50300 && is_callable('\\Sodium\\randombytes_buf')) {
require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_bytes_libsodium.php';
} elseif (method_exists('Sodium', 'randombytes_buf')) {
require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_bytes_libsodium_legacy.php';
}
}
/**
* Reading directly from /dev/urandom:
*/
if (DIRECTORY_SEPARATOR === '/') {
// DIRECTORY_SEPARATOR === '/' on Unix-like OSes -- this is a fast
// way to exclude Windows.
$RandomCompatUrandom = true;
$RandomCompat_basedir = ini_get('open_basedir');
if (!empty($RandomCompat_basedir)) {
$RandomCompat_open_basedir = explode(
PATH_SEPARATOR,
strtolower($RandomCompat_basedir)
);
$RandomCompatUrandom = (array() !== array_intersect(
array('/dev', '/dev/', '/dev/urandom'),
$RandomCompat_open_basedir
));
$RandomCompat_open_basedir = null;
}
if (
!is_callable('random_bytes')
&&
$RandomCompatUrandom
&&
@is_readable('/dev/urandom')
) {
// Error suppression on is_readable() in case of an open_basedir
// or safe_mode failure. All we care about is whether or not we
// can read it at this point. If the PHP environment is going to
// panic over trying to see if the file can be read in the first
// place, that is not helpful to us here.
// See random_bytes_dev_urandom.php
require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_bytes_dev_urandom.php';
}
// Unset variables after use
$RandomCompat_basedir = null;
} else {
$RandomCompatUrandom = false;
}
/**
* mcrypt_create_iv()
*
* We only want to use mcypt_create_iv() if:
*
* - random_bytes() hasn't already been defined
* - the mcrypt extensions is loaded
* - One of these two conditions is true:
* - We're on Windows (DIRECTORY_SEPARATOR !== '/')
* - We're not on Windows and /dev/urandom is readabale
* (i.e. we're not in a chroot jail)
* - Special case:
* - If we're not on Windows, but the PHP version is between
* 5.6.10 and 5.6.12, we don't want to use mcrypt. It will
* hang indefinitely. This is bad.
* - If we're on Windows, we want to use PHP >= 5.3.7 or else
* we get insufficient entropy errors.
*/
if (
!is_callable('random_bytes')
&&
// Windows on PHP < 5.3.7 is broken, but non-Windows is not known to be.
(DIRECTORY_SEPARATOR === '/' || PHP_VERSION_ID >= 50307)
&&
// Prevent this code from hanging indefinitely on non-Windows;
// see https://bugs.php.net/bug.php?id=69833
(
DIRECTORY_SEPARATOR !== '/' ||
(PHP_VERSION_ID <= 50609 || PHP_VERSION_ID >= 50613)
)
&&
extension_loaded('mcrypt')
) {
// See random_bytes_mcrypt.php
require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_bytes_mcrypt.php';
}
$RandomCompatUrandom = null;
/**
* This is a Windows-specific fallback, for when the mcrypt extension
* isn't loaded.
*/
if (
!is_callable('random_bytes')
&&
extension_loaded('com_dotnet')
&&
class_exists('COM')
) {
$RandomCompat_disabled_classes = preg_split(
'#\s*,\s*#',
strtolower(ini_get('disable_classes'))
);
if (!in_array('com', $RandomCompat_disabled_classes)) {
try {
$RandomCompatCOMtest = new COM('CAPICOM.Utilities.1');
/** @psalm-suppress TypeDoesNotContainType */
if (is_callable(array($RandomCompatCOMtest, 'GetRandom'))) {
// See random_bytes_com_dotnet.php
require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_bytes_com_dotnet.php';
}
} catch (com_exception $e) {
// Don't try to use it.
}
}
$RandomCompat_disabled_classes = null;
$RandomCompatCOMtest = null;
}
/**
* throw new Exception
*/
if (!is_callable('random_bytes')) {
/**
* We don't have any more options, so let's throw an exception right now
* and hope the developer won't let it fail silently.
*
* @param mixed $length
* @psalm-suppress InvalidReturnType
* @throws Exception
* @return string
*/
function random_bytes($length)
{
unset($length); // Suppress "variable not used" warnings.
throw new Exception(
'There is no suitable CSPRNG installed on your system'
);
return '';
}
}
}
if (!is_callable('random_int')) {
require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_int.php';
}
$RandomCompatDIR = null;

View File

@@ -0,0 +1,91 @@
<?php
/**
* Random_* Compatibility Library
* for using the new PHP 7 random_* API in PHP 5 projects
*
* The MIT License (MIT)
*
* Copyright (c) 2015 - 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.
*/
if (!is_callable('random_bytes')) {
/**
* Windows with PHP < 5.3.0 will not have the function
* openssl_random_pseudo_bytes() available, so let's use
* CAPICOM to work around this deficiency.
*
* @param int $bytes
*
* @throws Exception
*
* @return string
*/
function random_bytes($bytes)
{
try {
/** @var int $bytes */
$bytes = RandomCompat_intval($bytes);
} catch (TypeError $ex) {
throw new TypeError(
'random_bytes(): $bytes must be an integer'
);
}
if ($bytes < 1) {
throw new Error(
'Length must be greater than 0'
);
}
/** @var string $buf */
$buf = '';
if (!class_exists('COM')) {
throw new Error(
'COM does not exist'
);
}
/** @var COM $util */
$util = new COM('CAPICOM.Utilities.1');
$execCount = 0;
/**
* Let's not let it loop forever. If we run N times and fail to
* get N bytes of random data, then CAPICOM has failed us.
*/
do {
$buf .= base64_decode((string) $util->GetRandom($bytes, 0));
if (RandomCompat_strlen($buf) >= $bytes) {
/**
* Return our random entropy buffer here:
*/
return (string) RandomCompat_substr($buf, 0, $bytes);
}
++$execCount;
} while ($execCount < $bytes);
/**
* If we reach here, PHP has failed us.
*/
throw new Exception(
'Could not gather sufficient random data'
);
}
}

View File

@@ -0,0 +1,190 @@
<?php
/**
* Random_* Compatibility Library
* for using the new PHP 7 random_* API in PHP 5 projects
*
* The MIT License (MIT)
*
* Copyright (c) 2015 - 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.
*/
if (!defined('RANDOM_COMPAT_READ_BUFFER')) {
define('RANDOM_COMPAT_READ_BUFFER', 8);
}
if (!is_callable('random_bytes')) {
/**
* Unless open_basedir is enabled, use /dev/urandom for
* random numbers in accordance with best practices
*
* Why we use /dev/urandom and not /dev/random
* @ref https://www.2uo.de/myths-about-urandom
* @ref http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers
*
* @param int $bytes
*
* @throws Exception
*
* @return string
*/
function random_bytes($bytes)
{
/** @var resource $fp */
static $fp = null;
/**
* This block should only be run once
*/
if (empty($fp)) {
/**
* We don't want to ever read C:\dev\random, only /dev/urandom on
* Unix-like operating systems. While we guard against this
* condition in random.php, it doesn't hurt to be defensive in depth
* here.
*
* To that end, we only try to open /dev/urandom if we're on a Unix-
* like operating system (which means the directory separator is set
* to "/" not "\".
*/
if (DIRECTORY_SEPARATOR === '/') {
if (!is_readable('/dev/urandom')) {
throw new Exception(
'Environment misconfiguration: ' .
'/dev/urandom cannot be read.'
);
}
/**
* We use /dev/urandom if it is a char device.
* We never fall back to /dev/random
*/
/** @var resource|bool $fp */
$fp = fopen('/dev/urandom', 'rb');
if (is_resource($fp)) {
/** @var array<string, int> $st */
$st = fstat($fp);
if (($st['mode'] & 0170000) !== 020000) {
fclose($fp);
$fp = false;
}
}
}
if (is_resource($fp)) {
/**
* stream_set_read_buffer() does not exist in HHVM
*
* If we don't set the stream's read buffer to 0, PHP will
* internally buffer 8192 bytes, which can waste entropy
*
* stream_set_read_buffer returns 0 on success
*/
if (is_callable('stream_set_read_buffer')) {
stream_set_read_buffer($fp, RANDOM_COMPAT_READ_BUFFER);
}
if (is_callable('stream_set_chunk_size')) {
stream_set_chunk_size($fp, RANDOM_COMPAT_READ_BUFFER);
}
}
}
try {
/** @var int $bytes */
$bytes = RandomCompat_intval($bytes);
} catch (TypeError $ex) {
throw new TypeError(
'random_bytes(): $bytes must be an integer'
);
}
if ($bytes < 1) {
throw new Error(
'Length must be greater than 0'
);
}
/**
* This if() block only runs if we managed to open a file handle
*
* It does not belong in an else {} block, because the above
* if (empty($fp)) line is logic that should only be run once per
* page load.
*/
if (is_resource($fp)) {
/**
* @var int
*/
$remaining = $bytes;
/**
* @var string|bool
*/
$buf = '';
/**
* We use fread() in a loop to protect against partial reads
*/
do {
/**
* @var string|bool
*/
$read = fread($fp, $remaining);
if (!is_string($read)) {
/**
* We cannot safely read from the file. Exit the
* do-while loop and trigger the exception condition
*
* @var string|bool
*/
$buf = false;
break;
}
/**
* Decrease the number of bytes returned from remaining
*/
$remaining -= RandomCompat_strlen($read);
/**
* @var string $buf
*/
$buf .= $read;
} while ($remaining > 0);
/**
* Is our result valid?
* @var string|bool $buf
*/
if (is_string($buf)) {
if (RandomCompat_strlen($buf) === $bytes) {
/**
* Return our random entropy buffer here:
*/
return $buf;
}
}
}
/**
* If we reach here, PHP has failed us.
*/
throw new Exception(
'Error reading from source device'
);
}
}

View File

@@ -0,0 +1,91 @@
<?php
/**
* Random_* Compatibility Library
* for using the new PHP 7 random_* API in PHP 5 projects
*
* The MIT License (MIT)
*
* Copyright (c) 2015 - 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.
*/
if (!is_callable('random_bytes')) {
/**
* If the libsodium PHP extension is loaded, we'll use it above any other
* solution.
*
* libsodium-php project:
* @ref https://github.com/jedisct1/libsodium-php
*
* @param int $bytes
*
* @throws Exception
*
* @return string
*/
function random_bytes($bytes)
{
try {
/** @var int $bytes */
$bytes = RandomCompat_intval($bytes);
} catch (TypeError $ex) {
throw new TypeError(
'random_bytes(): $bytes must be an integer'
);
}
if ($bytes < 1) {
throw new Error(
'Length must be greater than 0'
);
}
/**
* \Sodium\randombytes_buf() doesn't allow more than 2147483647 bytes to be
* generated in one invocation.
*/
/** @var string|bool $buf */
if ($bytes > 2147483647) {
$buf = '';
for ($i = 0; $i < $bytes; $i += 1073741824) {
$n = ($bytes - $i) > 1073741824
? 1073741824
: $bytes - $i;
$buf .= \Sodium\randombytes_buf($n);
}
} else {
/** @var string|bool $buf */
$buf = \Sodium\randombytes_buf($bytes);
}
if (is_string($buf)) {
if (RandomCompat_strlen($buf) === $bytes) {
return $buf;
}
}
/**
* If we reach here, PHP has failed us.
*/
throw new Exception(
'Could not gather sufficient random data'
);
}
}

View File

@@ -0,0 +1,93 @@
<?php
/**
* Random_* Compatibility Library
* for using the new PHP 7 random_* API in PHP 5 projects
*
* The MIT License (MIT)
*
* Copyright (c) 2015 - 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.
*/
if (!is_callable('random_bytes')) {
/**
* If the libsodium PHP extension is loaded, we'll use it above any other
* solution.
*
* libsodium-php project:
* @ref https://github.com/jedisct1/libsodium-php
*
* @param int $bytes
*
* @throws Exception
*
* @return string
*/
function random_bytes($bytes)
{
try {
/** @var int $bytes */
$bytes = RandomCompat_intval($bytes);
} catch (TypeError $ex) {
throw new TypeError(
'random_bytes(): $bytes must be an integer'
);
}
if ($bytes < 1) {
throw new Error(
'Length must be greater than 0'
);
}
/**
* @var string
*/
$buf = '';
/**
* \Sodium\randombytes_buf() doesn't allow more than 2147483647 bytes to be
* generated in one invocation.
*/
if ($bytes > 2147483647) {
for ($i = 0; $i < $bytes; $i += 1073741824) {
$n = ($bytes - $i) > 1073741824
? 1073741824
: $bytes - $i;
$buf .= Sodium::randombytes_buf((int) $n);
}
} else {
$buf .= Sodium::randombytes_buf((int) $bytes);
}
if (is_string($buf)) {
if (RandomCompat_strlen($buf) === $bytes) {
return $buf;
}
}
/**
* If we reach here, PHP has failed us.
*/
throw new Exception(
'Could not gather sufficient random data'
);
}
}

View File

@@ -0,0 +1,79 @@
<?php
/**
* Random_* Compatibility Library
* for using the new PHP 7 random_* API in PHP 5 projects
*
* The MIT License (MIT)
*
* Copyright (c) 2015 - 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.
*/
if (!is_callable('random_bytes')) {
/**
* Powered by ext/mcrypt (and thankfully NOT libmcrypt)
*
* @ref https://bugs.php.net/bug.php?id=55169
* @ref https://github.com/php/php-src/blob/c568ffe5171d942161fc8dda066bce844bdef676/ext/mcrypt/mcrypt.c#L1321-L1386
*
* @param int $bytes
*
* @throws Exception
*
* @return string
*/
function random_bytes($bytes)
{
try {
/** @var int $bytes */
$bytes = RandomCompat_intval($bytes);
} catch (TypeError $ex) {
throw new TypeError(
'random_bytes(): $bytes must be an integer'
);
}
if ($bytes < 1) {
throw new Error(
'Length must be greater than 0'
);
}
/** @var string|bool $buf */
$buf = @mcrypt_create_iv((int) $bytes, (int) MCRYPT_DEV_URANDOM);
if (
is_string($buf)
&&
RandomCompat_strlen($buf) === $bytes
) {
/**
* Return our random entropy buffer here:
*/
return $buf;
}
/**
* If we reach here, PHP has failed us.
*/
throw new Exception(
'Could not gather sufficient random data'
);
}
}

View File

@@ -0,0 +1,204 @@
<?php
if (!is_callable('random_int')) {
/**
* Random_* Compatibility Library
* for using the new PHP 7 random_* API in PHP 5 projects
*
* The MIT License (MIT)
*
* Copyright (c) 2015 - 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.
*/
/**
* Fetch a random integer between $min and $max inclusive
*
* @param int $min
* @param int $max
*
* @throws Exception
*
* @return int
*/
function random_int($min, $max)
{
/**
* Type and input logic checks
*
* If you pass it a float in the range (~PHP_INT_MAX, PHP_INT_MAX)
* (non-inclusive), it will sanely cast it to an int. If you it's equal to
* ~PHP_INT_MAX or PHP_INT_MAX, we let it fail as not an integer. Floats
* lose precision, so the <= and => operators might accidentally let a float
* through.
*/
try {
/** @var int $min */
$min = RandomCompat_intval($min);
} catch (TypeError $ex) {
throw new TypeError(
'random_int(): $min must be an integer'
);
}
try {
/** @var int $max */
$max = RandomCompat_intval($max);
} catch (TypeError $ex) {
throw new TypeError(
'random_int(): $max must be an integer'
);
}
/**
* Now that we've verified our weak typing system has given us an integer,
* let's validate the logic then we can move forward with generating random
* integers along a given range.
*/
if ($min > $max) {
throw new Error(
'Minimum value must be less than or equal to the maximum value'
);
}
if ($max === $min) {
return (int) $min;
}
/**
* Initialize variables to 0
*
* We want to store:
* $bytes => the number of random bytes we need
* $mask => an integer bitmask (for use with the &) operator
* so we can minimize the number of discards
*/
$attempts = $bits = $bytes = $mask = $valueShift = 0;
/** @var int $attempts */
/** @var int $bits */
/** @var int $bytes */
/** @var int $mask */
/** @var int $valueShift */
/**
* At this point, $range is a positive number greater than 0. It might
* overflow, however, if $max - $min > PHP_INT_MAX. PHP will cast it to
* a float and we will lose some precision.
*
* @var int|float $range
*/
$range = $max - $min;
/**
* Test for integer overflow:
*/
if (!is_int($range)) {
/**
* Still safely calculate wider ranges.
* Provided by @CodesInChaos, @oittaa
*
* @ref https://gist.github.com/CodesInChaos/03f9ea0b58e8b2b8d435
*
* We use ~0 as a mask in this case because it generates all 1s
*
* @ref https://eval.in/400356 (32-bit)
* @ref http://3v4l.org/XX9r5 (64-bit)
*/
$bytes = PHP_INT_SIZE;
/** @var int $mask */
$mask = ~0;
} else {
/**
* $bits is effectively ceil(log($range, 2)) without dealing with
* type juggling
*/
while ($range > 0) {
if ($bits % 8 === 0) {
++$bytes;
}
++$bits;
$range >>= 1;
/** @var int $mask */
$mask = $mask << 1 | 1;
}
$valueShift = $min;
}
/** @var int $val */
$val = 0;
/**
* Now that we have our parameters set up, let's begin generating
* random integers until one falls between $min and $max
*/
/** @psalm-suppress RedundantCondition */
do {
/**
* The rejection probability is at most 0.5, so this corresponds
* to a failure probability of 2^-128 for a working RNG
*/
if ($attempts > 128) {
throw new Exception(
'random_int: RNG is broken - too many rejections'
);
}
/**
* Let's grab the necessary number of random bytes
*/
$randomByteString = random_bytes($bytes);
/**
* Let's turn $randomByteString into an integer
*
* This uses bitwise operators (<< and |) to build an integer
* out of the values extracted from ord()
*
* Example: [9F] | [6D] | [32] | [0C] =>
* 159 + 27904 + 3276800 + 201326592 =>
* 204631455
*/
$val &= 0;
for ($i = 0; $i < $bytes; ++$i) {
$val |= ord($randomByteString[$i]) << ($i * 8);
}
/** @var int $val */
/**
* Apply mask
*/
$val &= $mask;
$val += $valueShift;
++$attempts;
/**
* If $val overflows to a floating point number,
* ... or is larger than $max,
* ... or smaller than $min,
* then try again.
*/
} while (!is_int($val) || $val > $max || $val < $min);
return (int) $val;
}
}

16
vendor/paragonie/sodium_compat/LICENSE vendored Normal file
View File

@@ -0,0 +1,16 @@
ISC License
Copyright (c) 2016-2023, Paragon Initiative Enterprises <security at paragonie dot com>
Copyright (c) 2013-2019, Frank Denis <j at pureftpd dot org>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

415
vendor/paragonie/sodium_compat/README.md vendored Normal file
View File

@@ -0,0 +1,415 @@
# Sodium Compat
[![Build Status](https://github.com/paragonie/sodium_compat/actions/workflows/ci.yml/badge.svg)](https://github.com/paragonie/sodium_compat/actions)
[![Psalm Status](https://github.com/paragonie/sodium_compat/actions/workflows/psalm.yml/badge.svg)](https://github.com/paragonie/sodium_compat/actions)
[![Windows Build Status](https://ci.appveyor.com/api/projects/status/itcx1vgmfqiawgbe?svg=true)](https://ci.appveyor.com/project/paragonie-scott/sodium-compat)
[![Latest Stable Version](https://poser.pugx.org/paragonie/sodium_compat/v/stable)](https://packagist.org/packages/paragonie/sodium_compat)
[![Latest Unstable Version](https://poser.pugx.org/paragonie/sodium_compat/v/unstable)](https://packagist.org/packages/paragonie/sodium_compat)
[![License](https://poser.pugx.org/paragonie/sodium_compat/license)](https://packagist.org/packages/paragonie/sodium_compat)
[![Downloads](https://img.shields.io/packagist/dt/paragonie/sodium_compat.svg)](https://packagist.org/packages/paragonie/sodium_compat)
Sodium Compat is a pure PHP polyfill for the Sodium cryptography library
(libsodium), a core extension in PHP 7.2.0+ and otherwise [available in PECL](https://pecl.php.net/package/libsodium).
If you have the PHP extension installed, Sodium Compat will opportunistically
and transparently use the PHP extension instead of our implementation.
## Major Versions and Branches
sodium_compat v1.21.0 was the last v1.x release from the master branch. From now
on, all future releases that support PHP 5.2 - 5.6 and 32-bit integers will be
[in the `v1.x` branch](v1.x).
Newer versions of sodium_compat (i.e., v2.0.0) will continue to live in the master
branch, unless a new major version is needed. The goal of this work is to improve
code readability and performance, while reducing boilerplate code.
When in doubt, refer to the README file in [the master branch](https://github.com/paragonie/sodium_compat/blob/master/README.md)
for the latest in version information.
### Which version should I use?
| sodium_compat version | PHP versions supported | 32-bit support? | Branch |
|-----------------------|------------------------|-----------------|---------------------------------------------------------------|
| `v1.x.y` | 5.2.4 - LATEST | YES | [v1.x](https://github.com/paragonie/sodium_compat/tree/v1.x) |
| `v2.x.y` | 7.2 - LATEST | NO | **master** |
If you need 32-bit PHP support (`PHP_INT_SIZE == 4`), continue using sodium_compat v1.x.
If you want improved performance and smaller dependencies, use v2.x.
We recommend libraries and frameworks set a Composer version constraint as follows:
```javascript
{
"require": {
/* ... */
"paragonie/sodium_compat": ">= 1"
/* ... */
}
}
```
Applications should, conversely, specify the actual version that matters to them
and their deployments.
## IMPORTANT!
This cryptography library has not been formally audited by an independent third
party that specializes in cryptography or cryptanalysis.
If you require such an audit before you can use sodium_compat in your projects
and have the funds for such an audit, please open an issue or contact
`security at paragonie dot com` so we can help get the ball rolling.
However, sodium_compat has been adopted by high profile open source projects,
such as [Joomla!](https://github.com/joomla/joomla-cms/blob/459d74686d2a638ec51149d7c44ddab8075852be/composer.json#L40)
and [Magento](https://github.com/magento/magento2/blob/8fd89cfdf52c561ac0ca7bc20fd38ef688e201b0/composer.json#L44).
Furthermore, sodium_compat was developed by Paragon Initiative Enterprises, a
company that *specializes* in secure PHP development and PHP cryptography, and
has been informally reviewed by many other security experts who also specialize
in PHP.
If you'd like to learn more about the defensive security measures we've taken
to prevent sodium_compat from being a source of vulnerability in your systems,
please read [*Cryptographically Secure PHP Development*](https://paragonie.com/blog/2017/02/cryptographically-secure-php-development).
# Installing Sodium Compat
If you're using Composer:
```bash
composer require paragonie/sodium_compat
```
### Install From Source
If you're not using Composer, download a [release tarball](https://github.com/paragonie/sodium_compat/releases)
(which should be signed with [our GnuPG public key](https://paragonie.com/static/gpg-public-key.txt)), extract
its contents, then include our `autoload.php` script in your project.
```php
<?php
require_once "/path/to/sodium_compat/autoload.php";
```
### PHP Archives (Phar) Releases
Since version 1.3.0, [sodium_compat releases](https://github.com/paragonie/sodium_compat/releases) include a
PHP Archive (.phar file) and associated GPG signature. First, download both files and verify them with our
GPG public key, like so:
```bash
# Getting our public key from the keyserver:
gpg --fingerprint 7F52D5C61D1255C731362E826B97A1C2826404DA
if [ $? -ne 0 ]; then
echo -e "\033[33mDownloading PGP Public Key...\033[0m"
gpg --keyserver pgp.mit.edu --recv-keys 7F52D5C61D1255C731362E826B97A1C2826404DA
# Security <security@paragonie.com>
gpg --fingerprint 7F52D5C61D1255C731362E826B97A1C2826404DA
if [ $? -ne 0 ]; then
echo -e "\033[31mCould not download PGP public key for verification\033[0m"
exit 1
fi
fi
# Verifying the PHP Archive
gpg --verify sodium-compat.phar.sig sodium-compat.phar
```
Now, simply include this .phar file in your application.
```php
<?php
require_once "/path/to/sodium-compat.phar";
```
# Support
[Commercial support for libsodium](https://download.libsodium.org/doc/commercial_support/) is available
from multiple vendors. If you need help using sodium_compat in one of your projects, [contact Paragon Initiative Enterprises](https://paragonie.com/contact).
Non-commercial report will be facilitated through [Github issues](https://github.com/paragonie/sodium_compat/issues).
We offer no guarantees of our availability to resolve questions about integrating sodium_compat into third-party
software for free, but will strive to fix any bugs (security-related or otherwise) in our library.
## 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).
# Using Sodium Compat
## True Polyfill
As per the [second vote on the libsodium RFC](https://wiki.php.net/rfc/libsodium#proposed_voting_choices),
PHP 7.2 uses `sodium_*` instead of `\Sodium\*`.
```php
<?php
require_once "/path/to/sodium_compat/autoload.php";
$alice_kp = sodium_crypto_sign_keypair();
$alice_sk = sodium_crypto_sign_secretkey($alice_kp);
$alice_pk = sodium_crypto_sign_publickey($alice_kp);
$message = 'This is a test message.';
$signature = sodium_crypto_sign_detached($message, $alice_sk);
if (sodium_crypto_sign_verify_detached($signature, $message, $alice_pk)) {
echo 'OK', PHP_EOL;
} else {
throw new Exception('Invalid signature');
}
```
## Polyfill For the Old PECL Extension API
If you're using PHP 5.3.0 or newer and do not have the PECL extension installed,
you can just use the [standard ext/sodium API features as-is](https://paragonie.com/book/pecl-libsodium)
and the polyfill will work its magic.
```php
<?php
require_once "/path/to/sodium_compat/autoload.php";
$alice_kp = \Sodium\crypto_sign_keypair();
$alice_sk = \Sodium\crypto_sign_secretkey($alice_kp);
$alice_pk = \Sodium\crypto_sign_publickey($alice_kp);
$message = 'This is a test message.';
$signature = \Sodium\crypto_sign_detached($message, $alice_sk);
if (\Sodium\crypto_sign_verify_detached($signature, $message, $alice_pk)) {
echo 'OK', PHP_EOL;
} else {
throw new Exception('Invalid signature');
}
```
The polyfill does not expose this API on PHP < 5.3, or if you have the PHP
extension installed already.
## General-Use Polyfill
If your users are on PHP < 5.3, or you want to write code that will work
whether or not the PECL extension is available, you'll want to use the
**`ParagonIE_Sodium_Compat`** class for most of your libsodium needs.
The above example, written for general use:
```php
<?php
require_once "/path/to/sodium_compat/autoload.php";
$alice_kp = ParagonIE_Sodium_Compat::crypto_sign_keypair();
$alice_sk = ParagonIE_Sodium_Compat::crypto_sign_secretkey($alice_kp);
$alice_pk = ParagonIE_Sodium_Compat::crypto_sign_publickey($alice_kp);
$message = 'This is a test message.';
$signature = ParagonIE_Sodium_Compat::crypto_sign_detached($message, $alice_sk);
if (ParagonIE_Sodium_Compat::crypto_sign_verify_detached($signature, $message, $alice_pk)) {
echo 'OK', PHP_EOL;
} else {
throw new Exception('Invalid signature');
}
```
Generally: If you replace `\Sodium\ ` with `ParagonIE_Sodium_Compat::`, any
code already written for the libsodium PHP extension should work with our
polyfill without additional code changes.
Since this doesn't require a namespace, this API *is* exposed on PHP 5.2.
Since version 0.7.0, we have our own namespaced API (`ParagonIE\Sodium\*`) to allow brevity
in software that uses PHP 5.3+. This is useful if you want to use our file cryptography
features without writing `ParagonIE_Sodium_File` every time. This is not exposed on PHP < 5.3,
so if your project supports PHP < 5.3, use the underscore method instead.
To learn how to use Libsodium, read [*Using Libsodium in PHP Projects*](https://paragonie.com/book/pecl-libsodium).
## Help, Sodium_Compat is Slow! How can I make it fast?
There are three ways to make it fast:
1. Use a newer version of PHP (at least 7.2).
2. [Install the libsodium PHP extension from PECL](https://paragonie.com/book/pecl-libsodium/read/00-intro.md#installing-libsodium).
3. Only if the previous two options are not available for you:
1. Verify that [the processor you're using actually implements constant-time multiplication](https://bearssl.org/ctmul.html).
Sodium_compat does, but it must trade some speed in order to attain cross-platform security.
2. Only if you are 100% certain that your processor is safe, you can set `ParagonIE_Sodium_Compat::$fastMult = true;`
without harming the security of your cryptography keys. If your processor *isn't* safe, then decide whether you
want speed or security because you can't have both.
### How can I tell if sodium_compat will be slow, at runtime?
Since version 1.8, you can use the `polyfill_is_fast()` static method to
determine if sodium_compat will be slow at runtime.
```php
<?php
if (ParagonIE_Sodium_Compat::polyfill_is_fast()) {
// Use libsodium now
$process->execute();
} else {
// Defer to a cron job or other sort of asynchronous process
$process->enqueue();
}
```
### Help, my PHP only has 32-Bit Integers! It's super slow!
If the `PHP_INT_SIZE` constant equals `4` instead of `8` (PHP 5 on Windows,
Linux on i386, etc.), you will run into **significant performance issues**.
In particular: public-key cryptography (encryption and signatures)
is affected. There is nothing we can do about that.
The root cause of these performance issues has to do with implementing cryptography
algorithms in constant-time using 16-bit limbs (to avoid overflow) in pure PHP.
To mitigate these performance issues, simply install PHP 7.2 or newer and enable
the `sodium` extension.
Affected users are encouraged to install the sodium extension (or libsodium from
older version of PHP).
Windows users on PHP 5 may be able to simply upgrade to PHP 7 and the slowdown
will be greatly reduced.
## Documentation
First, you'll want to read the [Libsodium Quick Reference](https://paragonie.com/blog/2017/06/libsodium-quick-reference-quick-comparison-similar-functions-and-which-one-use).
It aims to answer, "Which function should I use for [common problem]?".
If you don't find the answers in the Quick Reference page, check out
[*Using Libsodium in PHP Projects*](https://paragonie.com/book/pecl-libsodium).
Finally, the [official libsodium documentation](https://download.libsodium.org/doc/)
(which was written for the C library, not the PHP library) also contains a lot of
insightful technical information you may find helpful.
## API Coverage
**Recommended reading:** [Libsodium Quick Reference](https://paragonie.com/blog/2017/06/libsodium-quick-reference-quick-comparison-similar-functions-and-which-one-use)
* Mainline NaCl Features
* `crypto_auth()`
* `crypto_auth_verify()`
* `crypto_box()`
* `crypto_box_open()`
* `crypto_scalarmult()`
* `crypto_secretbox()`
* `crypto_secretbox_open()`
* `crypto_sign()`
* `crypto_sign_open()`
* PECL Libsodium Features
* `crypto_aead_aegis128l_encrypt()`
* `crypto_aead_aegis128l_decrypt()`
* `crypto_aead_aegis256_encrypt()`
* `crypto_aead_aegis256_decrypt()`
* `crypto_aead_aes256gcm_encrypt()`
* `crypto_aead_aes256gcm_decrypt()`
* `crypto_aead_chacha20poly1305_encrypt()`
* `crypto_aead_chacha20poly1305_decrypt()`
* `crypto_aead_chacha20poly1305_ietf_encrypt()`
* `crypto_aead_chacha20poly1305_ietf_decrypt()`
* `crypto_aead_xchacha20poly1305_ietf_encrypt()`
* `crypto_aead_xchacha20poly1305_ietf_decrypt()`
* `crypto_box_xchacha20poly1305()`
* `crypto_box_xchacha20poly1305_open()`
* `crypto_box_seal()`
* `crypto_box_seal_open()`
* `crypto_generichash()`
* `crypto_generichash_init()`
* `crypto_generichash_update()`
* `crypto_generichash_final()`
* `crypto_kx()`
* `crypto_secretbox_xchacha20poly1305()`
* `crypto_secretbox_xchacha20poly1305_open()`
* `crypto_shorthash()`
* `crypto_sign_detached()`
* `crypto_sign_ed25519_pk_to_curve25519()`
* `crypto_sign_ed25519_sk_to_curve25519()`
* `crypto_sign_verify_detached()`
* For advanced users only:
* `crypto_core_ristretto255_add()`
* `crypto_core_ristretto255_from_hash()`
* `crypto_core_ristretto255_is_valid_point()`
* `crypto_core_ristretto255_random()`
* `crypto_core_ristretto255_scalar_add()`
* `crypto_core_ristretto255_scalar_complement()`
* `crypto_core_ristretto255_scalar_invert()`
* `crypto_core_ristretto255_scalar_mul()`
* `crypto_core_ristretto255_scalar_negate()`
* `crypto_core_ristretto255_scalar_random()`
* `crypto_core_ristretto255_scalar_reduce()`
* `crypto_core_ristretto255_scalar_sub()`
* `crypto_core_ristretto255_sub()`
* `crypto_scalarmult_ristretto255_base()`
* `crypto_scalarmult_ristretto255()`
* `crypto_stream()`
* `crypto_stream_keygen()`
* `crypto_stream_xor()`
* `crypto_stream_xchacha20()`
* `crypto_stream_xchacha20_keygen()`
* `crypto_stream_xchacha20_xor()`
* `crypto_stream_xchacha20_xor_ic()`
* Other utilities (e.g. `crypto_*_keypair()`)
* `add()`
* `base642bin()`
* `bin2base64()`
* `bin2hex()`
* `hex2bin()`
* `crypto_kdf_derive_from_key()`
* `crypto_kx_client_session_keys()`
* `crypto_kx_server_session_keys()`
* `crypto_secretstream_xchacha20poly1305_init_push()`
* `crypto_secretstream_xchacha20poly1305_push()`
* `crypto_secretstream_xchacha20poly1305_init_pull()`
* `crypto_secretstream_xchacha20poly1305_pull()`
* `crypto_secretstream_xchacha20poly1305_rekey()`
* `pad()`
* `unpad()`
### Cryptography Primitives Provided
* **X25519** - Elliptic Curve Diffie Hellman over Curve25519
* **Ed25519** - Edwards curve Digital Signature Algorithm over Curve25519
* **Xsalsa20** - Extended-nonce Salsa20 stream cipher
* **ChaCha20** - Stream cipher
* **Xchacha20** - Extended-nonce ChaCha20 stream cipher
* **Poly1305** - Polynomial Evaluation Message Authentication Code modulo 2^130 - 5
* **BLAKE2b** - Cryptographic Hash Function
* **SipHash-2-4** - Fast hash, but not collision-resistant; ideal for hash tables.
### Features Excluded from this Polyfill
* `sodium_memzero()` - Although we expose this API endpoint, we can't reliably
zero buffers from PHP.
If you have the PHP extension installed, sodium_compat
will use the native implementation to zero out the string provided. Otherwise
it will throw a `SodiumException`.
* `sodium_crypto_pwhash()` - It's not feasible to polyfill scrypt or Argon2
into PHP and get reasonable performance. Users would feel motivated to select
parameters that downgrade security to avoid denial of service (DoS) attacks.
The only winning move is not to play.
If ext/sodium or ext/libsodium is installed, these API methods will fallthrough
to the extension. Otherwise, our polyfill library will throw a `SodiumException`.
To detect support for Argon2i at runtime, use
`ParagonIE_Sodium_Compat::crypto_pwhash_is_available()`, which returns a
boolean value (`TRUE` or `FALSE`).
* Libsodium's HKDF API (`crypto_kdf_hkdf_*()`) is not included because PHP has
its own [HMAC features](https://php.met/hash_hmac) amd it was not deemed necessary.
### PHPCompatibility Ruleset
For sodium_compat users and that utilize [`PHPCompatibility`](https://github.com/PHPCompatibility/PHPCompatibility)
in their CI process, there is now a custom ruleset available which can be used
to prevent false positives being thrown by `PHPCompatibility` for the native
PHP functionality being polyfilled by this repo.
You can find the repo for the `PHPCompatibilityParagonieSodiumCompat` ruleset
here [on Github](https://github.com/PHPCompatibility/PHPCompatibilityParagonie)
and [on Packagist](https://packagist.org/packages/phpcompatibility/phpcompatibility-paragonie).

View File

@@ -0,0 +1,31 @@
<?php
/*
This file should only ever be loaded on PHP 7+
*/
if (PHP_VERSION_ID < 70000) {
return;
}
spl_autoload_register(function ($class) {
$namespace = 'ParagonIE_Sodium_';
// Does the class use the namespace prefix?
$len = strlen($namespace);
if (strncmp($namespace, $class, $len) !== 0) {
// no, move to the next registered autoloader
return false;
}
// Get the relative class name
$relative_class = substr($class, $len);
// Replace the namespace prefix with the base directory, replace namespace
// separators with directory separators in the relative class name, append
// with .php
$file = dirname(__FILE__) . '/src/' . str_replace('_', '/', $relative_class) . '.php';
// if the file exists, require it
if (file_exists($file)) {
require_once $file;
return true;
}
return false;
});

View File

@@ -0,0 +1,81 @@
<?php
if (PHP_VERSION_ID < 70000) {
if (!is_callable('sodiumCompatAutoloader')) {
/**
* Sodium_Compat autoloader.
*
* @param string $class Class name to be autoloaded.
*
* @return bool Stop autoloading?
*/
function sodiumCompatAutoloader($class)
{
$namespace = 'ParagonIE_Sodium_';
// Does the class use the namespace prefix?
$len = strlen($namespace);
if (strncmp($namespace, $class, $len) !== 0) {
// no, move to the next registered autoloader
return false;
}
// Get the relative class name
$relative_class = substr($class, $len);
// Replace the namespace prefix with the base directory, replace namespace
// separators with directory separators in the relative class name, append
// with .php
$file = dirname(__FILE__) . '/src/' . str_replace('_', '/', $relative_class) . '.php';
// if the file exists, require it
if (file_exists($file)) {
require_once $file;
return true;
}
return false;
}
// Now that we have an autoloader, let's register it!
spl_autoload_register('sodiumCompatAutoloader');
}
} else {
require_once dirname(__FILE__) . '/autoload-php7.php';
}
/* Explicitly, always load the Compat class: */
if (!class_exists('ParagonIE_Sodium_Compat', false)) {
require_once dirname(__FILE__) . '/src/Compat.php';
}
if (!class_exists('SodiumException', false)) {
require_once dirname(__FILE__) . '/src/SodiumException.php';
}
if (PHP_VERSION_ID >= 50300) {
// Namespaces didn't exist before 5.3.0, so don't even try to use this
// unless PHP >= 5.3.0
require_once dirname(__FILE__) . '/lib/namespaced.php';
require_once dirname(__FILE__) . '/lib/sodium_compat.php';
if (!defined('SODIUM_CRYPTO_AEAD_AEGIS128L_KEYBYTES')) {
require_once dirname(__FILE__) . '/lib/php84compat_const.php';
}
} else {
require_once dirname(__FILE__) . '/src/PHP52/SplFixedArray.php';
}
if (PHP_VERSION_ID < 70200 || !extension_loaded('sodium')) {
if (PHP_VERSION_ID >= 50300 && !defined('SODIUM_CRYPTO_SCALARMULT_BYTES')) {
require_once dirname(__FILE__) . '/lib/php72compat_const.php';
}
if (PHP_VERSION_ID >= 70000) {
assert(class_exists('ParagonIE_Sodium_Compat'), 'Possible filesystem/autoloader bug?');
} else {
assert(class_exists('ParagonIE_Sodium_Compat'));
}
require_once(dirname(__FILE__) . '/lib/php72compat.php');
} elseif (!function_exists('sodium_crypto_stream_xchacha20_xor')) {
// Older versions of {PHP, ext/sodium} will not define these
require_once(dirname(__FILE__) . '/lib/php72compat.php');
}
if (PHP_VERSION_ID < 80400 || !extension_loaded('sodium')) {
require_once dirname(__FILE__) . '/lib/php84compat.php';
}
require_once(dirname(__FILE__) . '/lib/stream-xchacha20.php');
require_once(dirname(__FILE__) . '/lib/ristretto255.php');

View File

@@ -0,0 +1,87 @@
{
"name": "paragonie/sodium_compat",
"description": "Pure PHP implementation of libsodium; uses the PHP extension if it exists",
"keywords": [
"PHP",
"cryptography",
"elliptic curve",
"elliptic curve cryptography",
"Pure-PHP cryptography",
"side-channel resistant",
"Curve25519",
"X25519",
"ECDH",
"Elliptic Curve Diffie-Hellman",
"Ed25519",
"RFC 7748",
"RFC 8032",
"EdDSA",
"Edwards-curve Digital Signature Algorithm",
"ChaCha20",
"Salsa20",
"Xchacha20",
"Xsalsa20",
"Poly1305",
"BLAKE2b",
"public-key cryptography",
"secret-key cryptography",
"AEAD",
"Chapoly",
"Salpoly",
"ChaCha20-Poly1305",
"XSalsa20-Poly1305",
"XChaCha20-Poly1305",
"encryption",
"authentication",
"libsodium"
],
"license": "ISC",
"authors": [
{
"name": "Paragon Initiative Enterprises",
"email": "security@paragonie.com"
},
{
"name": "Frank Denis",
"email": "jedisct1@pureftpd.org"
}
],
"autoload": {
"files": ["autoload.php"]
},
"repositories": [
{
"type": "git",
"url": "https://github.com/garex/phpunit"
},
{
"type": "git",
"url": "https://github.com/garex/phpunit-mock-objects"
}
],
"require": {
"php": "^5.2.4|^5.3|^5.4|^5.5|^5.6|^7|^8",
"xrstf/composer-php52": "1.*",
"paragonie/random_compat": ">=1"
},
"minimum-stability": "dev",
"require-dev": {
"phpunit/phpunit-php52": "dev-3.6.12-php52",
"phpunit/phpunit-mock-objects-php52": "dev-1.1.0-php52"
},
"scripts": {
"post-install-cmd": [
"xrstf\\Composer52\\Generator::onPostInstallCmd"
],
"post-update-cmd": [
"xrstf\\Composer52\\Generator::onPostInstallCmd"
],
"post-autoload-dump": [
"xrstf\\Composer52\\Generator::onPostInstallCmd"
]
},
"suggest": {
"ext-libsodium": "PHP < 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security.",
"ext-sodium": "PHP >= 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security."
}
}

View File

@@ -0,0 +1,66 @@
{
"name": "paragonie/sodium_compat",
"description": "Pure PHP implementation of libsodium; uses the PHP extension if it exists",
"keywords": [
"PHP",
"cryptography",
"elliptic curve",
"elliptic curve cryptography",
"Pure-PHP cryptography",
"side-channel resistant",
"Curve25519",
"X25519",
"ECDH",
"Elliptic Curve Diffie-Hellman",
"Ed25519",
"RFC 7748",
"RFC 8032",
"EdDSA",
"Edwards-curve Digital Signature Algorithm",
"ChaCha20",
"Salsa20",
"Xchacha20",
"Xsalsa20",
"Poly1305",
"BLAKE2b",
"public-key cryptography",
"secret-key cryptography",
"AEAD",
"Chapoly",
"Salpoly",
"ChaCha20-Poly1305",
"XSalsa20-Poly1305",
"XChaCha20-Poly1305",
"encryption",
"authentication",
"libsodium"
],
"license": "ISC",
"authors": [
{
"name": "Paragon Initiative Enterprises",
"email": "security@paragonie.com"
},
{
"name": "Frank Denis",
"email": "jedisct1@pureftpd.org"
}
],
"autoload": {
"files": ["autoload.php"]
},
"require": {
"php": "^5.2.4|^5.3|^5.4|^5.5|^5.6|^7|^8",
"paragonie/random_compat": ">=1"
},
"require-dev": {
"phpunit/phpunit": "^3|^4|^5|^6|^7|^8|^9"
},
"scripts": {
"test": "phpunit"
},
"suggest": {
"ext-libsodium": "PHP < 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security.",
"ext-sodium": "PHP >= 7.0: Better performance, password hashing (Argon2i), secure memory management (memzero), and better security."
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace Sodium;
require_once dirname(dirname(__FILE__)) . '/autoload.php';
use ParagonIE_Sodium_Compat;
const CRYPTO_AEAD_AES256GCM_KEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_AEAD_AES256GCM_KEYBYTES;
const CRYPTO_AEAD_AES256GCM_NSECBYTES = ParagonIE_Sodium_Compat::CRYPTO_AEAD_AES256GCM_NSECBYTES;
const CRYPTO_AEAD_AES256GCM_NPUBBYTES = ParagonIE_Sodium_Compat::CRYPTO_AEAD_AES256GCM_NPUBBYTES;
const CRYPTO_AEAD_AES256GCM_ABYTES = ParagonIE_Sodium_Compat::CRYPTO_AEAD_AES256GCM_ABYTES;
const CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES;
const CRYPTO_AEAD_CHACHA20POLY1305_NSECBYTES = ParagonIE_Sodium_Compat::CRYPTO_AEAD_CHACHA20POLY1305_NSECBYTES;
const CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES = ParagonIE_Sodium_Compat::CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES;
const CRYPTO_AEAD_CHACHA20POLY1305_ABYTES = ParagonIE_Sodium_Compat::CRYPTO_AEAD_CHACHA20POLY1305_ABYTES;
const CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES;
const CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES = ParagonIE_Sodium_Compat::CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES;
const CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES = ParagonIE_Sodium_Compat::CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES;
const CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES = ParagonIE_Sodium_Compat::CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES;
const CRYPTO_AUTH_BYTES = ParagonIE_Sodium_Compat::CRYPTO_AUTH_BYTES;
const CRYPTO_AUTH_KEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_AUTH_KEYBYTES;
const CRYPTO_BOX_SEALBYTES = ParagonIE_Sodium_Compat::CRYPTO_BOX_SEALBYTES;
const CRYPTO_BOX_SECRETKEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_BOX_SECRETKEYBYTES;
const CRYPTO_BOX_PUBLICKEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_BOX_PUBLICKEYBYTES;
const CRYPTO_BOX_KEYPAIRBYTES = ParagonIE_Sodium_Compat::CRYPTO_BOX_KEYPAIRBYTES;
const CRYPTO_BOX_MACBYTES = ParagonIE_Sodium_Compat::CRYPTO_BOX_MACBYTES;
const CRYPTO_BOX_NONCEBYTES = ParagonIE_Sodium_Compat::CRYPTO_BOX_NONCEBYTES;
const CRYPTO_BOX_SEEDBYTES = ParagonIE_Sodium_Compat::CRYPTO_BOX_SEEDBYTES;
const CRYPTO_KX_BYTES = ParagonIE_Sodium_Compat::CRYPTO_KX_BYTES;
const CRYPTO_KX_SEEDBYTES = ParagonIE_Sodium_Compat::CRYPTO_KX_SEEDBYTES;
const CRYPTO_KX_PUBLICKEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_KX_PUBLICKEYBYTES;
const CRYPTO_KX_SECRETKEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_KX_SECRETKEYBYTES;
const CRYPTO_GENERICHASH_BYTES = ParagonIE_Sodium_Compat::CRYPTO_GENERICHASH_BYTES;
const CRYPTO_GENERICHASH_BYTES_MIN = ParagonIE_Sodium_Compat::CRYPTO_GENERICHASH_BYTES_MIN;
const CRYPTO_GENERICHASH_BYTES_MAX = ParagonIE_Sodium_Compat::CRYPTO_GENERICHASH_BYTES_MAX;
const CRYPTO_GENERICHASH_KEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_GENERICHASH_KEYBYTES;
const CRYPTO_GENERICHASH_KEYBYTES_MIN = ParagonIE_Sodium_Compat::CRYPTO_GENERICHASH_KEYBYTES_MIN;
const CRYPTO_GENERICHASH_KEYBYTES_MAX = ParagonIE_Sodium_Compat::CRYPTO_GENERICHASH_KEYBYTES_MAX;
const CRYPTO_SCALARMULT_BYTES = ParagonIE_Sodium_Compat::CRYPTO_SCALARMULT_BYTES;
const CRYPTO_SCALARMULT_SCALARBYTES = ParagonIE_Sodium_Compat::CRYPTO_SCALARMULT_SCALARBYTES;
const CRYPTO_SHORTHASH_BYTES = ParagonIE_Sodium_Compat::CRYPTO_SHORTHASH_BYTES;
const CRYPTO_SHORTHASH_KEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_SHORTHASH_KEYBYTES;
const CRYPTO_SECRETBOX_KEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_SECRETBOX_KEYBYTES;
const CRYPTO_SECRETBOX_MACBYTES = ParagonIE_Sodium_Compat::CRYPTO_SECRETBOX_MACBYTES;
const CRYPTO_SECRETBOX_NONCEBYTES = ParagonIE_Sodium_Compat::CRYPTO_SECRETBOX_NONCEBYTES;
const CRYPTO_SIGN_BYTES = ParagonIE_Sodium_Compat::CRYPTO_SIGN_BYTES;
const CRYPTO_SIGN_SEEDBYTES = ParagonIE_Sodium_Compat::CRYPTO_SIGN_SEEDBYTES;
const CRYPTO_SIGN_PUBLICKEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_SIGN_PUBLICKEYBYTES;
const CRYPTO_SIGN_SECRETKEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_SIGN_SECRETKEYBYTES;
const CRYPTO_SIGN_KEYPAIRBYTES = ParagonIE_Sodium_Compat::CRYPTO_SIGN_KEYPAIRBYTES;
const CRYPTO_STREAM_KEYBYTES = ParagonIE_Sodium_Compat::CRYPTO_STREAM_KEYBYTES;
const CRYPTO_STREAM_NONCEBYTES = ParagonIE_Sodium_Compat::CRYPTO_STREAM_NONCEBYTES;

View File

@@ -0,0 +1,48 @@
<?php
require_once dirname(dirname(__FILE__)) . '/autoload.php';
if (PHP_VERSION_ID < 50300) {
return;
}
/*
* This file is just for convenience, to allow developers to reduce verbosity when
* they add this project to their libraries.
*
* Replace this:
*
* $x = ParagonIE_Sodium_Compat::crypto_aead_xchacha20poly1305_encrypt(...$args);
*
* with this:
*
* use ParagonIE\Sodium\Compat;
*
* $x = Compat::crypto_aead_xchacha20poly1305_encrypt(...$args);
*/
spl_autoload_register(function ($class) {
if ($class[0] === '\\') {
$class = substr($class, 1);
}
$namespace = 'ParagonIE\\Sodium';
// Does the class use the namespace prefix?
$len = strlen($namespace);
if (strncmp($namespace, $class, $len) !== 0) {
// no, move to the next registered autoloader
return false;
}
// Get the relative class name
$relative_class = substr($class, $len);
// Replace the namespace prefix with the base directory, replace namespace
// separators with directory separators in the relative class name, append
// with .php
$file = dirname(dirname(__FILE__)) . '/namespaced/' . str_replace('\\', '/', $relative_class) . '.php';
// if the file exists, require it
if (file_exists($file)) {
require_once $file;
return true;
}
return false;
});

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,92 @@
<?php
const SODIUM_LIBRARY_MAJOR_VERSION = 9;
const SODIUM_LIBRARY_MINOR_VERSION = 1;
const SODIUM_LIBRARY_VERSION = '1.0.8';
const SODIUM_BASE64_VARIANT_ORIGINAL = 1;
const SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING = 3;
const SODIUM_BASE64_VARIANT_URLSAFE = 5;
const SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING = 7;
const SODIUM_CRYPTO_AEAD_AES256GCM_KEYBYTES = 32;
const SODIUM_CRYPTO_AEAD_AES256GCM_NSECBYTES = 0;
const SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES = 12;
const SODIUM_CRYPTO_AEAD_AES256GCM_ABYTES = 16;
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES = 32;
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NSECBYTES = 0;
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES = 8;
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_ABYTES = 16;
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES = 32;
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES = 0;
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES = 12;
const SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES = 16;
const SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_KEYBYTES = 32;
const SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NSECBYTES = 0;
const SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES = 24;
const SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_ABYTES = 16;
const SODIUM_CRYPTO_AUTH_BYTES = 32;
const SODIUM_CRYPTO_AUTH_KEYBYTES = 32;
const SODIUM_CRYPTO_BOX_SEALBYTES = 16;
const SODIUM_CRYPTO_BOX_SECRETKEYBYTES = 32;
const SODIUM_CRYPTO_BOX_PUBLICKEYBYTES = 32;
const SODIUM_CRYPTO_BOX_KEYPAIRBYTES = 64;
const SODIUM_CRYPTO_BOX_MACBYTES = 16;
const SODIUM_CRYPTO_BOX_NONCEBYTES = 24;
const SODIUM_CRYPTO_BOX_SEEDBYTES = 32;
const SODIUM_CRYPTO_KDF_BYTES_MIN = 16;
const SODIUM_CRYPTO_KDF_BYTES_MAX = 64;
const SODIUM_CRYPTO_KDF_CONTEXTBYTES = 8;
const SODIUM_CRYPTO_KDF_KEYBYTES = 32;
const SODIUM_CRYPTO_KX_BYTES = 32;
const SODIUM_CRYPTO_KX_PRIMITIVE = 'x25519blake2b';
const SODIUM_CRYPTO_KX_SEEDBYTES = 32;
const SODIUM_CRYPTO_KX_KEYPAIRBYTES = 64;
const SODIUM_CRYPTO_KX_PUBLICKEYBYTES = 32;
const SODIUM_CRYPTO_KX_SECRETKEYBYTES = 32;
const SODIUM_CRYPTO_KX_SESSIONKEYBYTES = 32;
const SODIUM_CRYPTO_GENERICHASH_BYTES = 32;
const SODIUM_CRYPTO_GENERICHASH_BYTES_MIN = 16;
const SODIUM_CRYPTO_GENERICHASH_BYTES_MAX = 64;
const SODIUM_CRYPTO_GENERICHASH_KEYBYTES = 32;
const SODIUM_CRYPTO_GENERICHASH_KEYBYTES_MIN = 16;
const SODIUM_CRYPTO_GENERICHASH_KEYBYTES_MAX = 64;
const SODIUM_CRYPTO_PWHASH_SALTBYTES = 16;
const SODIUM_CRYPTO_PWHASH_STRPREFIX = '$argon2id$';
const SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13 = 1;
const SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13 = 2;
const SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE = 33554432;
const SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE = 4;
const SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE = 134217728;
const SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE = 6;
const SODIUM_CRYPTO_PWHASH_MEMLIMIT_SENSITIVE = 536870912;
const SODIUM_CRYPTO_PWHASH_OPSLIMIT_SENSITIVE = 8;
const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES = 32;
const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_STRPREFIX = '$7$';
const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_INTERACTIVE = 534288;
const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_INTERACTIVE = 16777216;
const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_SENSITIVE = 33554432;
const SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_SENSITIVE = 1073741824;
const SODIUM_CRYPTO_SCALARMULT_BYTES = 32;
const SODIUM_CRYPTO_SCALARMULT_SCALARBYTES = 32;
const SODIUM_CRYPTO_SHORTHASH_BYTES = 8;
const SODIUM_CRYPTO_SHORTHASH_KEYBYTES = 16;
const SODIUM_CRYPTO_SECRETBOX_KEYBYTES = 32;
const SODIUM_CRYPTO_SECRETBOX_MACBYTES = 16;
const SODIUM_CRYPTO_SECRETBOX_NONCEBYTES = 24;
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES = 17;
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES = 24;
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_KEYBYTES = 32;
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PUSH = 0;
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PULL = 1;
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY = 2;
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL = 3;
const SODIUM_CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX = 0x3fffffff80;
const SODIUM_CRYPTO_SIGN_BYTES = 64;
const SODIUM_CRYPTO_SIGN_SEEDBYTES = 32;
const SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES = 32;
const SODIUM_CRYPTO_SIGN_SECRETKEYBYTES = 64;
const SODIUM_CRYPTO_SIGN_KEYPAIRBYTES = 96;
const SODIUM_CRYPTO_STREAM_KEYBYTES = 32;
const SODIUM_CRYPTO_STREAM_NONCEBYTES = 24;
const SODIUM_CRYPTO_STREAM_XCHACHA20_KEYBYTES = 32;
const SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES = 24;

View File

@@ -0,0 +1,130 @@
<?php
require_once dirname(dirname(__FILE__)) . '/autoload.php';
/**
* This file will monkey patch the pure-PHP implementation in place of the
* PECL functions and constants, but only if they do not already exist.
*
* Thus, the functions or constants just proxy to the appropriate
* ParagonIE_Sodium_Compat method or class constant, respectively.
*/
foreach (array(
'CRYPTO_AEAD_AESGIS128L_KEYBYTES',
'CRYPTO_AEAD_AESGIS128L_NSECBYTES',
'CRYPTO_AEAD_AESGIS128L_NPUBBYTES',
'CRYPTO_AEAD_AESGIS128L_ABYTES',
'CRYPTO_AEAD_AESGIS256_KEYBYTES',
'CRYPTO_AEAD_AESGIS256_NSECBYTES',
'CRYPTO_AEAD_AESGIS256_NPUBBYTES',
'CRYPTO_AEAD_AESGIS256_ABYTES',
) as $constant
) {
if (!defined("SODIUM_$constant") && defined("ParagonIE_Sodium_Compat::$constant")) {
define("SODIUM_$constant", constant("ParagonIE_Sodium_Compat::$constant"));
}
}
if (!is_callable('sodium_crypto_aead_aegis128l_decrypt')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_aead_aegis128l_decrypt()
* @param string $ciphertext
* @param string $additional_data
* @param string $nonce
* @param string $key
* @return string
* @throws SodiumException
*/
function sodium_crypto_aead_aegis128l_decrypt(
$ciphertext,
$additional_data,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_aead_aegis128l_decrypt(
$ciphertext,
$additional_data,
$nonce,
$key
);
}
}
if (!is_callable('sodium_crypto_aead_aegis128l_encrypt')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_aead_aegis128l_encrypt()
* @param string $message
* @param string $additional_data
* @param string $nonce
* @param string $key
* @return string
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_aead_aegis128l_encrypt(
#[\SensitiveParameter]
$message,
$additional_data,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_aead_aegis128l_encrypt(
$message,
$additional_data,
$nonce,
$key
);
}
}
if (!is_callable('sodium_crypto_aead_aegis256_decrypt')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_aead_aegis256_encrypt()
* @param string $ciphertext
* @param string $additional_data
* @param string $nonce
* @param string $key
* @return string
* @throws SodiumException
*/
function sodium_crypto_aead_aegis256_decrypt(
$ciphertext,
$additional_data,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_aead_aegis256_decrypt(
$ciphertext,
$additional_data,
$nonce,
$key
);
}
}
if (!is_callable('sodium_crypto_aead_aegis256_encrypt')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_aead_aegis256_encrypt()
* @param string $message
* @param string $additional_data
* @param string $nonce
* @param string $key
* @return string
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_aead_aegis256_encrypt(
#[\SensitiveParameter]
$message,
$additional_data,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_aead_aegis256_encrypt(
$message,
$additional_data,
$nonce,
$key
);
}
}

View File

@@ -0,0 +1,10 @@
<?php
const SODIUM_CRYPTO_AEAD_AEGIS128L_KEYBYTES = 16;
const SODIUM_CRYPTO_AEAD_AEGIS128L_NSECBYTES = 0;
const SODIUM_CRYPTO_AEAD_AEGIS128L_NPUBBYTES = 32;
const SODIUM_CRYPTO_AEAD_AEGIS128L_ABYTES = 32;
const SODIUM_CRYPTO_AEAD_AEGIS256_KEYBYTES = 32;
const SODIUM_CRYPTO_AEAD_AEGIS256_NSECBYTES = 0;
const SODIUM_CRYPTO_AEAD_AEGIS256_NPUBBYTES = 32;
const SODIUM_CRYPTO_AEAD_AEGIS256_ABYTES = 32;

View File

@@ -0,0 +1,277 @@
<?php
if (!defined('SODIUM_CRYPTO_CORE_RISTRETTO255_BYTES')) {
define(
'SODIUM_CRYPTO_CORE_RISTRETTO255_BYTES',
ParagonIE_Sodium_Compat::CRYPTO_CORE_RISTRETTO255_BYTES
);
define('SODIUM_COMPAT_POLYFILLED_RISTRETTO255', true);
}
if (!defined('SODIUM_CRYPTO_CORE_RISTRETTO255_HASHBYTES')) {
define(
'SODIUM_CRYPTO_CORE_RISTRETTO255_HASHBYTES',
ParagonIE_Sodium_Compat::CRYPTO_CORE_RISTRETTO255_HASHBYTES
);
}
if (!defined('SODIUM_CRYPTO_CORE_RISTRETTO255_SCALARBYTES')) {
define(
'SODIUM_CRYPTO_CORE_RISTRETTO255_SCALARBYTES',
ParagonIE_Sodium_Compat::CRYPTO_CORE_RISTRETTO255_SCALARBYTES
);
}
if (!defined('SODIUM_CRYPTO_CORE_RISTRETTO255_NONREDUCEDSCALARBYTES')) {
define(
'SODIUM_CRYPTO_CORE_RISTRETTO255_NONREDUCEDSCALARBYTES',
ParagonIE_Sodium_Compat::CRYPTO_CORE_RISTRETTO255_NONREDUCEDSCALARBYTES
);
}
if (!defined('SODIUM_CRYPTO_SCALARMULT_RISTRETTO255_SCALARBYTES')) {
define(
'SODIUM_CRYPTO_SCALARMULT_RISTRETTO255_SCALARBYTES',
ParagonIE_Sodium_Compat::CRYPTO_SCALARMULT_RISTRETTO255_SCALARBYTES
);
}
if (!defined('SODIUM_CRYPTO_SCALARMULT_RISTRETTO255_BYTES')) {
define(
'SODIUM_CRYPTO_SCALARMULT_RISTRETTO255_BYTES',
ParagonIE_Sodium_Compat::CRYPTO_SCALARMULT_RISTRETTO255_BYTES
);
}
if (!is_callable('sodium_crypto_core_ristretto255_add')) {
/**
* @see ParagonIE_Sodium_Compat::ristretto255_add()
*
* @param string $p
* @param string $q
* @return string
* @throws SodiumException
*/
function sodium_crypto_core_ristretto255_add(
#[\SensitiveParameter]
$p,
#[\SensitiveParameter]
$q
) {
return ParagonIE_Sodium_Compat::ristretto255_add($p, $q, true);
}
}
if (!is_callable('sodium_crypto_core_ristretto255_from_hash')) {
/**
* @see ParagonIE_Sodium_Compat::ristretto255_from_hash()
*
* @param string $s
* @return string
* @throws SodiumException
*/
function sodium_crypto_core_ristretto255_from_hash(
#[\SensitiveParameter]
$s
) {
return ParagonIE_Sodium_Compat::ristretto255_from_hash($s, true);
}
}
if (!is_callable('sodium_crypto_core_ristretto255_is_valid_point')) {
/**
* @see ParagonIE_Sodium_Compat::ristretto255_is_valid_point()
*
* @param string $s
* @return bool
* @throws SodiumException
*/
function sodium_crypto_core_ristretto255_is_valid_point(
#[\SensitiveParameter]
$s
) {
return ParagonIE_Sodium_Compat::ristretto255_is_valid_point($s, true);
}
}
if (!is_callable('sodium_crypto_core_ristretto255_random')) {
/**
* @see ParagonIE_Sodium_Compat::ristretto255_random()
*
* @return string
* @throws SodiumException
*/
function sodium_crypto_core_ristretto255_random()
{
return ParagonIE_Sodium_Compat::ristretto255_random(true);
}
}
if (!is_callable('sodium_crypto_core_ristretto255_scalar_add')) {
/**
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_add()
*
* @param string $x
* @param string $y
* @return string
* @throws SodiumException
*/
function sodium_crypto_core_ristretto255_scalar_add(
#[\SensitiveParameter]
$x,
#[\SensitiveParameter]
$y
) {
return ParagonIE_Sodium_Compat::ristretto255_scalar_add($x, $y, true);
}
}
if (!is_callable('sodium_crypto_core_ristretto255_scalar_complement')) {
/**
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_complement()
*
* @param string $s
* @return string
* @throws SodiumException
*/
function sodium_crypto_core_ristretto255_scalar_complement(
#[\SensitiveParameter]
$s
) {
return ParagonIE_Sodium_Compat::ristretto255_scalar_complement($s, true);
}
}
if (!is_callable('sodium_crypto_core_ristretto255_scalar_invert')) {
/**
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_invert()
*
* @param string $p
* @return string
* @throws SodiumException
*/
function sodium_crypto_core_ristretto255_scalar_invert(
#[\SensitiveParameter]
$p
) {
return ParagonIE_Sodium_Compat::ristretto255_scalar_invert($p, true);
}
}
if (!is_callable('sodium_crypto_core_ristretto255_scalar_mul')) {
/**
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_mul()
*
* @param string $x
* @param string $y
* @return string
* @throws SodiumException
*/
function sodium_crypto_core_ristretto255_scalar_mul(
#[\SensitiveParameter]
$x,
#[\SensitiveParameter]
$y
) {
return ParagonIE_Sodium_Compat::ristretto255_scalar_mul($x, $y, true);
}
}
if (!is_callable('sodium_crypto_core_ristretto255_scalar_negate')) {
/**
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_negate()
*
* @param string $s
* @return string
* @throws SodiumException
*/
function sodium_crypto_core_ristretto255_scalar_negate(
#[\SensitiveParameter]
$s
) {
return ParagonIE_Sodium_Compat::ristretto255_scalar_negate($s, true);
}
}
if (!is_callable('sodium_crypto_core_ristretto255_scalar_random')) {
/**
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_random()
*
* @return string
* @throws SodiumException
*/
function sodium_crypto_core_ristretto255_scalar_random()
{
return ParagonIE_Sodium_Compat::ristretto255_scalar_random(true);
}
}
if (!is_callable('sodium_crypto_core_ristretto255_scalar_reduce')) {
/**
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_reduce()
*
* @param string $s
* @return string
* @throws SodiumException
*/
function sodium_crypto_core_ristretto255_scalar_reduce(
#[\SensitiveParameter]
$s
) {
return ParagonIE_Sodium_Compat::ristretto255_scalar_reduce($s, true);
}
}
if (!is_callable('sodium_crypto_core_ristretto255_scalar_sub')) {
/**
* @see ParagonIE_Sodium_Compat::ristretto255_scalar_sub()
*
* @param string $x
* @param string $y
* @return string
* @throws SodiumException
*/
function sodium_crypto_core_ristretto255_scalar_sub(
#[\SensitiveParameter]
$x,
#[\SensitiveParameter]
$y
) {
return ParagonIE_Sodium_Compat::ristretto255_scalar_sub($x, $y, true);
}
}
if (!is_callable('sodium_crypto_core_ristretto255_sub')) {
/**
* @see ParagonIE_Sodium_Compat::ristretto255_sub()
*
* @param string $p
* @param string $q
* @return string
* @throws SodiumException
*/
function sodium_crypto_core_ristretto255_sub(
#[\SensitiveParameter]
$p,
#[\SensitiveParameter]
$q
) {
return ParagonIE_Sodium_Compat::ristretto255_sub($p, $q, true);
}
}
if (!is_callable('sodium_crypto_scalarmult_ristretto255')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_scalarmult_ristretto255()
* @param string $n
* @param string $p
* @return string
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_scalarmult_ristretto255(
#[\SensitiveParameter]
$n,
#[\SensitiveParameter]
$p
) {
return ParagonIE_Sodium_Compat::scalarmult_ristretto255($n, $p, true);
}
}
if (!is_callable('sodium_crypto_scalarmult_ristretto255_base')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_scalarmult_ristretto255_base()
* @param string $n
* @return string
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_scalarmult_ristretto255_base(
#[\SensitiveParameter]
$n
) {
return ParagonIE_Sodium_Compat::scalarmult_ristretto255_base($n, true);
}
}

View File

@@ -0,0 +1,999 @@
<?php
namespace Sodium;
require_once dirname(dirname(__FILE__)) . '/autoload.php';
use ParagonIE_Sodium_Compat;
/**
* This file will monkey patch the pure-PHP implementation in place of the
* PECL functions, but only if they do not already exist.
*
* Thus, the functions just proxy to the appropriate ParagonIE_Sodium_Compat
* method.
*/
if (!is_callable('\\Sodium\\bin2hex')) {
/**
* @see ParagonIE_Sodium_Compat::bin2hex()
* @param string $string
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function bin2hex(
#[\SensitiveParameter]
$string
) {
return ParagonIE_Sodium_Compat::bin2hex($string);
}
}
if (!is_callable('\\Sodium\\compare')) {
/**
* @see ParagonIE_Sodium_Compat::compare()
* @param string $a
* @param string $b
* @return int
* @throws \SodiumException
* @throws \TypeError
*/
function compare(
#[\SensitiveParameter]
$a,
#[\SensitiveParameter]
$b
) {
return ParagonIE_Sodium_Compat::compare($a, $b);
}
}
if (!is_callable('\\Sodium\\crypto_aead_aes256gcm_decrypt')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_decrypt()
* @param string $message
* @param string $assocData
* @param string $nonce
* @param string $key
* @return string|bool
*/
function crypto_aead_aes256gcm_decrypt(
$message,
$assocData,
$nonce,
#[\SensitiveParameter]
$key
) {
try {
return ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_decrypt($message, $assocData, $nonce, $key);
} catch (\TypeError $ex) {
return false;
} catch (\SodiumException $ex) {
return false;
}
}
}
if (!is_callable('\\Sodium\\crypto_aead_aes256gcm_encrypt')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_encrypt()
* @param string $message
* @param string $assocData
* @param string $nonce
* @param string $key
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_aead_aes256gcm_encrypt(
#[\SensitiveParameter]
$message,
$assocData,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_encrypt($message, $assocData, $nonce, $key);
}
}
if (!is_callable('\\Sodium\\crypto_aead_aes256gcm_is_available')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_is_available()
* @return bool
*/
function crypto_aead_aes256gcm_is_available()
{
return ParagonIE_Sodium_Compat::crypto_aead_aes256gcm_is_available();
}
}
if (!is_callable('\\Sodium\\crypto_aead_chacha20poly1305_decrypt')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_decrypt()
* @param string $message
* @param string $assocData
* @param string $nonce
* @param string $key
* @return string|bool
*/
function crypto_aead_chacha20poly1305_decrypt(
$message,
$assocData,
$nonce,
#[\SensitiveParameter]
$key
) {
try {
return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_decrypt($message, $assocData, $nonce, $key);
} catch (\TypeError $ex) {
return false;
} catch (\SodiumException $ex) {
return false;
}
}
}
if (!is_callable('\\Sodium\\crypto_aead_chacha20poly1305_encrypt')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_encrypt()
* @param string $message
* @param string $assocData
* @param string $nonce
* @param string $key
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_aead_chacha20poly1305_encrypt(
#[\SensitiveParameter]
$message,
$assocData,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_encrypt($message, $assocData, $nonce, $key);
}
}
if (!is_callable('\\Sodium\\crypto_aead_chacha20poly1305_ietf_decrypt')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_ietf_decrypt()
* @param string $message
* @param string $assocData
* @param string $nonce
* @param string $key
* @return string|bool
*/
function crypto_aead_chacha20poly1305_ietf_decrypt(
$message,
$assocData,
$nonce,
#[\SensitiveParameter]
$key
) {
try {
return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_ietf_decrypt($message, $assocData, $nonce, $key);
} catch (\TypeError $ex) {
return false;
} catch (\SodiumException $ex) {
return false;
}
}
}
if (!is_callable('\\Sodium\\crypto_aead_chacha20poly1305_ietf_encrypt')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_ietf_encrypt()
* @param string $message
* @param string $assocData
* @param string $nonce
* @param string $key
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_aead_chacha20poly1305_ietf_encrypt(
#[\SensitiveParameter]
$message,
$assocData,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_aead_chacha20poly1305_ietf_encrypt($message, $assocData, $nonce, $key);
}
}
if (!is_callable('\\Sodium\\crypto_auth')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_auth()
* @param string $message
* @param string $key
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_auth(
$message,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_auth($message, $key);
}
}
if (!is_callable('\\Sodium\\crypto_auth_verify')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_auth_verify()
* @param string $mac
* @param string $message
* @param string $key
* @return bool
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_auth_verify(
$mac,
$message,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_auth_verify($mac, $message, $key);
}
}
if (!is_callable('\\Sodium\\crypto_box')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_box()
* @param string $message
* @param string $nonce
* @param string $kp
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_box(
#[\SensitiveParameter]
$message,
$nonce,
#[\SensitiveParameter]
$kp
) {
return ParagonIE_Sodium_Compat::crypto_box($message, $nonce, $kp);
}
}
if (!is_callable('\\Sodium\\crypto_box_keypair')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_box_keypair()
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_box_keypair()
{
return ParagonIE_Sodium_Compat::crypto_box_keypair();
}
}
if (!is_callable('\\Sodium\\crypto_box_keypair_from_secretkey_and_publickey')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_box_keypair_from_secretkey_and_publickey()
* @param string $sk
* @param string $pk
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_box_keypair_from_secretkey_and_publickey(
#[\SensitiveParameter]
$sk,
$pk
) {
return ParagonIE_Sodium_Compat::crypto_box_keypair_from_secretkey_and_publickey($sk, $pk);
}
}
if (!is_callable('\\Sodium\\crypto_box_open')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_box_open()
* @param string $message
* @param string $nonce
* @param string $kp
* @return string|bool
*/
function crypto_box_open(
#[\SensitiveParameter]
$message,
$nonce,
#[\SensitiveParameter]
$kp
) {
try {
return ParagonIE_Sodium_Compat::crypto_box_open($message, $nonce, $kp);
} catch (\TypeError $ex) {
return false;
} catch (\SodiumException $ex) {
return false;
}
}
}
if (!is_callable('\\Sodium\\crypto_box_publickey')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_box_publickey()
* @param string $keypair
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_box_publickey(
#[\SensitiveParameter]
$keypair
) {
return ParagonIE_Sodium_Compat::crypto_box_publickey($keypair);
}
}
if (!is_callable('\\Sodium\\crypto_box_publickey_from_secretkey')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_box_publickey_from_secretkey()
* @param string $sk
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_box_publickey_from_secretkey(
#[\SensitiveParameter]
$sk
) {
return ParagonIE_Sodium_Compat::crypto_box_publickey_from_secretkey($sk);
}
}
if (!is_callable('\\Sodium\\crypto_box_seal')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_box_seal_open()
* @param string $message
* @param string $publicKey
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_box_seal(
#[\SensitiveParameter]
$message,
$publicKey
) {
return ParagonIE_Sodium_Compat::crypto_box_seal($message, $publicKey);
}
}
if (!is_callable('\\Sodium\\crypto_box_seal_open')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_box_seal_open()
* @param string $message
* @param string $kp
* @return string|bool
*/
function crypto_box_seal_open(
$message,
#[\SensitiveParameter]
$kp
) {
try {
return ParagonIE_Sodium_Compat::crypto_box_seal_open($message, $kp);
} catch (\TypeError $ex) {
return false;
} catch (\SodiumException $ex) {
return false;
}
}
}
if (!is_callable('\\Sodium\\crypto_box_secretkey')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_box_secretkey()
* @param string $keypair
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_box_secretkey(
#[\SensitiveParameter]
$keypair
) {
return ParagonIE_Sodium_Compat::crypto_box_secretkey($keypair);
}
}
if (!is_callable('\\Sodium\\crypto_generichash')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_generichash()
* @param string $message
* @param string|null $key
* @param int $outLen
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_generichash(
$message,
#[\SensitiveParameter]
$key = null,
$outLen = 32
) {
return ParagonIE_Sodium_Compat::crypto_generichash($message, $key, $outLen);
}
}
if (!is_callable('\\Sodium\\crypto_generichash_final')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_generichash_final()
* @param string|null $ctx
* @param int $outputLength
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_generichash_final(
#[\SensitiveParameter]
&$ctx,
$outputLength = 32
) {
return ParagonIE_Sodium_Compat::crypto_generichash_final($ctx, $outputLength);
}
}
if (!is_callable('\\Sodium\\crypto_generichash_init')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_generichash_init()
* @param string|null $key
* @param int $outLen
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_generichash_init(
#[\SensitiveParameter]
$key = null,
$outLen = 32
) {
return ParagonIE_Sodium_Compat::crypto_generichash_init($key, $outLen);
}
}
if (!is_callable('\\Sodium\\crypto_generichash_update')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_generichash_update()
* @param string|null $ctx
* @param string $message
* @return void
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_generichash_update(
#[\SensitiveParameter]
&$ctx,
$message = ''
) {
ParagonIE_Sodium_Compat::crypto_generichash_update($ctx, $message);
}
}
if (!is_callable('\\Sodium\\crypto_kx')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_kx()
* @param string $my_secret
* @param string $their_public
* @param string $client_public
* @param string $server_public
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_kx(
#[\SensitiveParameter]
$my_secret,
$their_public,
$client_public,
$server_public
) {
return ParagonIE_Sodium_Compat::crypto_kx(
$my_secret,
$their_public,
$client_public,
$server_public,
true
);
}
}
if (!is_callable('\\Sodium\\crypto_pwhash')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_pwhash()
* @param int $outlen
* @param string $passwd
* @param string $salt
* @param int $opslimit
* @param int $memlimit
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_pwhash(
$outlen,
#[\SensitiveParameter]
$passwd,
$salt,
$opslimit,
$memlimit
) {
return ParagonIE_Sodium_Compat::crypto_pwhash($outlen, $passwd, $salt, $opslimit, $memlimit);
}
}
if (!is_callable('\\Sodium\\crypto_pwhash_str')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_pwhash_str()
* @param string $passwd
* @param int $opslimit
* @param int $memlimit
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_pwhash_str(
#[\SensitiveParameter]
$passwd,
$opslimit,
$memlimit
) {
return ParagonIE_Sodium_Compat::crypto_pwhash_str($passwd, $opslimit, $memlimit);
}
}
if (!is_callable('\\Sodium\\crypto_pwhash_str_verify')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_pwhash_str_verify()
* @param string $passwd
* @param string $hash
* @return bool
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_pwhash_str_verify(
#[\SensitiveParameter]
$passwd,
#[\SensitiveParameter]
$hash
) {
return ParagonIE_Sodium_Compat::crypto_pwhash_str_verify($passwd, $hash);
}
}
if (!is_callable('\\Sodium\\crypto_pwhash_scryptsalsa208sha256')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256()
* @param int $outlen
* @param string $passwd
* @param string $salt
* @param int $opslimit
* @param int $memlimit
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_pwhash_scryptsalsa208sha256(
$outlen,
#[\SensitiveParameter]
$passwd,
#[\SensitiveParameter]
$salt,
$opslimit,
$memlimit
) {
return ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256($outlen, $passwd, $salt, $opslimit, $memlimit);
}
}
if (!is_callable('\\Sodium\\crypto_pwhash_scryptsalsa208sha256_str')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256_str()
* @param string $passwd
* @param int $opslimit
* @param int $memlimit
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_pwhash_scryptsalsa208sha256_str(
#[\SensitiveParameter]
$passwd,
$opslimit,
$memlimit
) {
return ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256_str($passwd, $opslimit, $memlimit);
}
}
if (!is_callable('\\Sodium\\crypto_pwhash_scryptsalsa208sha256_str_verify')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256_str_verify()
* @param string $passwd
* @param string $hash
* @return bool
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_pwhash_scryptsalsa208sha256_str_verify(
#[\SensitiveParameter]
$passwd,
#[\SensitiveParameter]
$hash
) {
return ParagonIE_Sodium_Compat::crypto_pwhash_scryptsalsa208sha256_str_verify($passwd, $hash);
}
}
if (!is_callable('\\Sodium\\crypto_scalarmult')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_scalarmult()
* @param string $n
* @param string $p
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_scalarmult(
#[\SensitiveParameter]
$n,
$p
) {
return ParagonIE_Sodium_Compat::crypto_scalarmult($n, $p);
}
}
if (!is_callable('\\Sodium\\crypto_scalarmult_base')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_scalarmult_base()
* @param string $n
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_scalarmult_base(
#[\SensitiveParameter]
$n
) {
return ParagonIE_Sodium_Compat::crypto_scalarmult_base($n);
}
}
if (!is_callable('\\Sodium\\crypto_secretbox')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_secretbox()
* @param string $message
* @param string $nonce
* @param string $key
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_secretbox(
#[\SensitiveParameter]
$message,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_secretbox($message, $nonce, $key);
}
}
if (!is_callable('\\Sodium\\crypto_secretbox_open')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_secretbox_open()
* @param string $message
* @param string $nonce
* @param string $key
* @return string|bool
*/
function crypto_secretbox_open(
$message,
$nonce,
#[\SensitiveParameter]
$key
) {
try {
return ParagonIE_Sodium_Compat::crypto_secretbox_open($message, $nonce, $key);
} catch (\TypeError $ex) {
return false;
} catch (\SodiumException $ex) {
return false;
}
}
}
if (!is_callable('\\Sodium\\crypto_shorthash')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_shorthash()
* @param string $message
* @param string $key
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_shorthash(
$message,
#[\SensitiveParameter]
$key = ''
) {
return ParagonIE_Sodium_Compat::crypto_shorthash($message, $key);
}
}
if (!is_callable('\\Sodium\\crypto_sign')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_sign()
* @param string $message
* @param string $sk
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_sign(
$message,
#[\SensitiveParameter]
$sk
) {
return ParagonIE_Sodium_Compat::crypto_sign($message, $sk);
}
}
if (!is_callable('\\Sodium\\crypto_sign_detached')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_sign_detached()
* @param string $message
* @param string $sk
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_sign_detached(
$message,
#[\SensitiveParameter]
$sk
) {
return ParagonIE_Sodium_Compat::crypto_sign_detached($message, $sk);
}
}
if (!is_callable('\\Sodium\\crypto_sign_keypair')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_sign_keypair()
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_sign_keypair()
{
return ParagonIE_Sodium_Compat::crypto_sign_keypair();
}
}
if (!is_callable('\\Sodium\\crypto_sign_open')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_sign_open()
* @param string $signedMessage
* @param string $pk
* @return string|bool
*/
function crypto_sign_open($signedMessage, $pk)
{
try {
return ParagonIE_Sodium_Compat::crypto_sign_open($signedMessage, $pk);
} catch (\TypeError $ex) {
return false;
} catch (\SodiumException $ex) {
return false;
}
}
}
if (!is_callable('\\Sodium\\crypto_sign_publickey')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_sign_publickey()
* @param string $keypair
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_sign_publickey(
#[\SensitiveParameter]
$keypair
) {
return ParagonIE_Sodium_Compat::crypto_sign_publickey($keypair);
}
}
if (!is_callable('\\Sodium\\crypto_sign_publickey_from_secretkey')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_sign_publickey_from_secretkey()
* @param string $sk
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_sign_publickey_from_secretkey(
#[\SensitiveParameter]
$sk
) {
return ParagonIE_Sodium_Compat::crypto_sign_publickey_from_secretkey($sk);
}
}
if (!is_callable('\\Sodium\\crypto_sign_secretkey')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_sign_secretkey()
* @param string $keypair
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_sign_secretkey(
#[\SensitiveParameter]
$keypair
) {
return ParagonIE_Sodium_Compat::crypto_sign_secretkey($keypair);
}
}
if (!is_callable('\\Sodium\\crypto_sign_seed_keypair')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_sign_seed_keypair()
* @param string $seed
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_sign_seed_keypair(
#[\SensitiveParameter]
$seed
) {
return ParagonIE_Sodium_Compat::crypto_sign_seed_keypair($seed);
}
}
if (!is_callable('\\Sodium\\crypto_sign_verify_detached')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_sign_verify_detached()
* @param string $signature
* @param string $message
* @param string $pk
* @return bool
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_sign_verify_detached($signature, $message, $pk)
{
return ParagonIE_Sodium_Compat::crypto_sign_verify_detached($signature, $message, $pk);
}
}
if (!is_callable('\\Sodium\\crypto_sign_ed25519_pk_to_curve25519')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_sign_ed25519_pk_to_curve25519()
* @param string $pk
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_sign_ed25519_pk_to_curve25519($pk)
{
return ParagonIE_Sodium_Compat::crypto_sign_ed25519_pk_to_curve25519($pk);
}
}
if (!is_callable('\\Sodium\\crypto_sign_ed25519_sk_to_curve25519')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_sign_ed25519_sk_to_curve25519()
* @param string $sk
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_sign_ed25519_sk_to_curve25519(
#[\SensitiveParameter]
$sk
) {
return ParagonIE_Sodium_Compat::crypto_sign_ed25519_sk_to_curve25519($sk);
}
}
if (!is_callable('\\Sodium\\crypto_stream')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_stream()
* @param int $len
* @param string $nonce
* @param string $key
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_stream(
$len,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_stream($len, $nonce, $key);
}
}
if (!is_callable('\\Sodium\\crypto_stream_xor')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_stream_xor()
* @param string $message
* @param string $nonce
* @param string $key
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function crypto_stream_xor(
#[\SensitiveParameter]
$message,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_stream_xor($message, $nonce, $key);
}
}
if (!is_callable('\\Sodium\\hex2bin')) {
/**
* @see ParagonIE_Sodium_Compat::hex2bin()
* @param string $string
* @return string
* @throws \SodiumException
* @throws \TypeError
*/
function hex2bin(
#[\SensitiveParameter]
$string
) {
return ParagonIE_Sodium_Compat::hex2bin($string);
}
}
if (!is_callable('\\Sodium\\memcmp')) {
/**
* @see ParagonIE_Sodium_Compat::memcmp()
* @param string $a
* @param string $b
* @return int
* @throws \SodiumException
* @throws \TypeError
*/
function memcmp(
#[\SensitiveParameter]
$a,
#[\SensitiveParameter]
$b
) {
return ParagonIE_Sodium_Compat::memcmp($a, $b);
}
}
if (!is_callable('\\Sodium\\memzero')) {
/**
* @see ParagonIE_Sodium_Compat::memzero()
* @param string $str
* @return void
* @throws \SodiumException
* @throws \TypeError
*
* @psalm-suppress MissingParamType
* @psalm-suppress MissingReturnType
* @psalm-suppress ReferenceConstraintViolation
*/
function memzero(
#[\SensitiveParameter]
&$str
) {
ParagonIE_Sodium_Compat::memzero($str);
}
}
if (!is_callable('\\Sodium\\randombytes_buf')) {
/**
* @see ParagonIE_Sodium_Compat::randombytes_buf()
* @param int $amount
* @return string
* @throws \TypeError
*/
function randombytes_buf($amount)
{
return ParagonIE_Sodium_Compat::randombytes_buf($amount);
}
}
if (!is_callable('\\Sodium\\randombytes_uniform')) {
/**
* @see ParagonIE_Sodium_Compat::randombytes_uniform()
* @param int $upperLimit
* @return int
* @throws \SodiumException
* @throws \Error
*/
function randombytes_uniform($upperLimit)
{
return ParagonIE_Sodium_Compat::randombytes_uniform($upperLimit);
}
}
if (!is_callable('\\Sodium\\randombytes_random16')) {
/**
* @see ParagonIE_Sodium_Compat::randombytes_random16()
* @return int
*/
function randombytes_random16()
{
return ParagonIE_Sodium_Compat::randombytes_random16();
}
}
if (!defined('\\Sodium\\CRYPTO_AUTH_BYTES')) {
require_once dirname(__FILE__) . '/constants.php';
}

View File

@@ -0,0 +1,74 @@
<?php
if (!is_callable('sodium_crypto_stream_xchacha20')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_stream_xchacha20()
* @param int $len
* @param string $nonce
* @param string $key
* @return string
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_stream_xchacha20(
$len,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_stream_xchacha20($len, $nonce, $key, true);
}
}
if (!is_callable('sodium_crypto_stream_xchacha20_keygen')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_stream_xchacha20_keygen()
* @return string
* @throws Exception
*/
function sodium_crypto_stream_xchacha20_keygen()
{
return ParagonIE_Sodium_Compat::crypto_stream_xchacha20_keygen();
}
}
if (!is_callable('sodium_crypto_stream_xchacha20_xor')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_stream_xchacha20_xor()
* @param string $message
* @param string $nonce
* @param string $key
* @return string
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_stream_xchacha20_xor(
#[\SensitiveParameter]
$message,
$nonce,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_stream_xchacha20_xor($message, $nonce, $key, true);
}
}
if (!is_callable('sodium_crypto_stream_xchacha20_xor_ic')) {
/**
* @see ParagonIE_Sodium_Compat::crypto_stream_xchacha20_xor_ic()
* @param string $message
* @param string $nonce
* @param int $counter
* @param string $key
* @return string
* @throws SodiumException
* @throws TypeError
*/
function sodium_crypto_stream_xchacha20_xor_ic(
#[\SensitiveParameter]
$message,
$nonce,
$counter,
#[\SensitiveParameter]
$key
) {
return ParagonIE_Sodium_Compat::crypto_stream_xchacha20_xor_ic($message, $nonce, $counter, $key, true);
}
}

View File

@@ -0,0 +1,7 @@
<?php
namespace ParagonIE\Sodium;
class Compat extends \ParagonIE_Sodium_Compat
{
}

View File

@@ -0,0 +1,7 @@
<?php
namespace ParagonIE\Sodium\Core;
class BLAKE2b extends \ParagonIE_Sodium_Core_BLAKE2b
{
}

View File

@@ -0,0 +1,7 @@
<?php
namespace ParagonIE\Sodium\Core;
class ChaCha20 extends \ParagonIE_Sodium_Core_ChaCha20
{
}

View File

@@ -0,0 +1,7 @@
<?php
namespace ParagonIE\Sodium\Core\ChaCha20;
class Ctx extends \ParagonIE_Sodium_Core_ChaCha20_Ctx
{
}

View File

@@ -0,0 +1,7 @@
<?php
namespace ParagonIE\Sodium\Core\ChaCha20;
class IetfCtx extends \ParagonIE_Sodium_Core_ChaCha20_IetfCtx
{
}

View File

@@ -0,0 +1,7 @@
<?php
namespace ParagonIE\Sodium\Core;
class Curve25519 extends \ParagonIE_Sodium_Core_Curve25519
{
}

View File

@@ -0,0 +1,7 @@
<?php
namespace ParagonIE\Sodium\Core\Curve25519;
class Fe extends \ParagonIE_Sodium_Core_Curve25519_Fe
{
}

View File

@@ -0,0 +1,7 @@
<?php
namespace ParagonIE\Sodium\Core\Curve25519\Ge;
class Cached extends \ParagonIE_Sodium_Core_Curve25519_Ge_Cached
{
}

View File

@@ -0,0 +1,7 @@
<?php
namespace ParagonIE\Sodium\Core\Curve25519\Ge;
class P1p1 extends \ParagonIE_Sodium_Core_Curve25519_Ge_P1p1
{
}

View File

@@ -0,0 +1,7 @@
<?php
namespace ParagonIE\Sodium\Core\Curve25519\Ge;
class P2 extends \ParagonIE_Sodium_Core_Curve25519_Ge_P2
{
}

View File

@@ -0,0 +1,7 @@
<?php
namespace ParagonIE\Sodium\Core\Curve25519\Ge;
class P3 extends \ParagonIE_Sodium_Core_Curve25519_Ge_P3
{
}

View File

@@ -0,0 +1,7 @@
<?php
namespace ParagonIE\Sodium\Core\Curve25519\Ge;
class Precomp extends \ParagonIE_Sodium_Core_Curve25519_Ge_Precomp
{
}

View File

@@ -0,0 +1,7 @@
<?php
namespace ParagonIE\Sodium\Core\Curve25519;
class H extends \ParagonIE_Sodium_Core_Curve25519_H
{
}

View File

@@ -0,0 +1,7 @@
<?php
namespace ParagonIE\Sodium\Core;
class Ed25519 extends \ParagonIE_Sodium_Core_Ed25519
{
}

View File

@@ -0,0 +1,7 @@
<?php
namespace ParagonIE\Sodium\Core;
class HChaCha20 extends \ParagonIE_Sodium_Core_HChaCha20
{
}

View File

@@ -0,0 +1,7 @@
<?php
namespace ParagonIE\Sodium\Core;
class HSalsa20 extends \ParagonIE_Sodium_Core_HSalsa20
{
}

View File

@@ -0,0 +1,7 @@
<?php
namespace ParagonIE\Sodium\Core;
class Poly1305 extends \ParagonIE_Sodium_Core_Poly1305
{
}

View File

@@ -0,0 +1,7 @@
<?php
namespace ParagonIE\Sodium\Core\Poly1305;
class State extends \ParagonIE_Sodium_Core_Poly1305_State
{
}

View File

@@ -0,0 +1,7 @@
<?php
namespace ParagonIE\Sodium\Core;
class Salsa20 extends \ParagonIE_Sodium_Core_Salsa20
{
}

View File

@@ -0,0 +1,7 @@
<?php
namespace ParagonIE\Sodium\Core;
class SipHash extends \ParagonIE_Sodium_Core_SipHash
{
}

View File

@@ -0,0 +1,7 @@
<?php
namespace ParagonIE\Sodium\Core;
class Util extends \ParagonIE_Sodium_Core_Util
{
}

Some files were not shown because too many files have changed in this diff Show More