📚 doc blocks

This commit is contained in:
William Hall
2021-03-08 18:21:15 +00:00
parent 452d31bfbf
commit 33a32cb099
27 changed files with 378 additions and 7 deletions
@@ -4,8 +4,14 @@ namespace RobThree\Auth\Providers\Qr;
abstract class BaseHTTPQRCodeProvider implements IQRCodeProvider
{
/** @var bool */
protected $verifyssl;
/**
* @param string $url
*
* @return string|bool
*/
protected function getContent($url)
{
$curlhandle = curl_init();
+15
View File
@@ -4,6 +4,21 @@ namespace RobThree\Auth\Providers\Qr;
interface IQRCodeProvider
{
/**
* Generate and return the QR code to embed in a web page
*
* @param string $qrtext the value to encode in the QR code
* @param int $size the desired size of the QR code
*
* @return string file contents of the QR code
*/
public function getQRCodeImage($qrtext, $size);
/**
* Returns the appropriate mime type for the QR code
* that will be generated
*
* @return string
*/
public function getMimeType();
}
@@ -5,9 +5,17 @@ namespace RobThree\Auth\Providers\Qr;
// https://image-charts.com
class ImageChartsQRCodeProvider extends BaseHTTPQRCodeProvider
{
/** @var string */
public $errorcorrectionlevel;
/** @var int */
public $margin;
/**
* @param bool $verifyssl
* @param string $errorcorrectionlevel
* @param int $margin
*/
public function __construct($verifyssl = false, $errorcorrectionlevel = 'L', $margin = 1)
{
if (!is_bool($verifyssl)) {
@@ -20,16 +28,28 @@ class ImageChartsQRCodeProvider extends BaseHTTPQRCodeProvider
$this->margin = $margin;
}
/**
* {@inheritdoc}
*/
public function getMimeType()
{
return 'image/png';
}
/**
* {@inheritdoc}
*/
public function getQRCodeImage($qrtext, $size)
{
return $this->getContent($this->getUrl($qrtext, $size));
}
/**
* @param string $qrtext the value to encode in the QR code
* @param int $size the desired size of the QR code
*
* @return string file contents of the QR code
*/
public function getUrl($qrtext, $size)
{
return 'https://image-charts.com/chart?cht=qr'
+37
View File
@@ -5,13 +5,33 @@ namespace RobThree\Auth\Providers\Qr;
// http://goqr.me/api/doc/create-qr-code/
class QRServerProvider extends BaseHTTPQRCodeProvider
{
/** @var string */
public $errorcorrectionlevel;
/** @var int */
public $margin;
/** @var int */
public $qzone;
/** @var string */
public $bgcolor;
/** @var string */
public $color;
/** @var string */
public $format;
/**
* @param bool $verifyssl
* @param string $errorcorrectionlevel
* @param int $margin
* @param int $qzone
* @param string $bgcolor
* @param string $color
* @param string $format
*/
public function __construct($verifyssl = false, $errorcorrectionlevel = 'L', $margin = 4, $qzone = 1, $bgcolor = 'ffffff', $color = '000000', $format = 'png')
{
if (!is_bool($verifyssl)) {
@@ -28,6 +48,9 @@ class QRServerProvider extends BaseHTTPQRCodeProvider
$this->format = $format;
}
/**
* {@inheritdoc}
*/
public function getMimeType()
{
switch (strtolower($this->format)) {
@@ -46,16 +69,30 @@ class QRServerProvider extends BaseHTTPQRCodeProvider
throw new QRException(sprintf('Unknown MIME-type: %s', $this->format));
}
/**
* {@inheritdoc}
*/
public function getQRCodeImage($qrtext, $size)
{
return $this->getContent($this->getUrl($qrtext, $size));
}
/**
* @param string $value
*
* @return string
*/
private function decodeColor($value)
{
return vsprintf('%d-%d-%d', sscanf($value, "%02x%02x%02x"));
}
/**
* @param string $qrtext the value to encode in the QR code
* @param int|string $size the desired size of the QR code
*
* @return string file contents of the QR code
*/
public function getUrl($qrtext, $size)
{
return 'https://api.qrserver.com/v1/create-qr-code/'
+25 -2
View File
@@ -5,13 +5,24 @@ namespace RobThree\Auth\Providers\Qr;
// http://qrickit.com/qrickit_apps/qrickit_api.php
class QRicketProvider extends BaseHTTPQRCodeProvider
{
/** @var string */
public $errorcorrectionlevel;
public $margin;
public $qzone;
/** @var string */
public $bgcolor;
/** @var string */
public $color;
/** @var string */
public $format;
/**
* @param string $errorcorrectionlevel
* @param string $bgcolor
* @param string $color
* @param string $format
*/
public function __construct($errorcorrectionlevel = 'L', $bgcolor = 'ffffff', $color = '000000', $format = 'p')
{
$this->verifyssl = false;
@@ -22,6 +33,9 @@ class QRicketProvider extends BaseHTTPQRCodeProvider
$this->format = $format;
}
/**
* {@inheritdoc}
*/
public function getMimeType()
{
switch (strtolower($this->format)) {
@@ -35,11 +49,20 @@ class QRicketProvider extends BaseHTTPQRCodeProvider
throw new QRException(sprintf('Unknown MIME-type: %s', $this->format));
}
/**
* {@inheritdoc}
*/
public function getQRCodeImage($qrtext, $size)
{
return $this->getContent($this->getUrl($qrtext, $size));
}
/**
* @param string $qrtext the value to encode in the QR code
* @param int|string $size the desired size of the QR code
*
* @return string file contents of the QR code
*/
public function getUrl($qrtext, $size)
{
return 'http://qrickit.com/api/qr'
+6
View File
@@ -4,11 +4,17 @@ namespace RobThree\Auth\Providers\Rng;
class CSRNGProvider implements IRNGProvider
{
/**
* {@inheritdoc}
*/
public function getRandomBytes($bytecount)
{
return random_bytes($bytecount); // PHP7+
}
/**
* {@inheritdoc}
*/
public function isCryptographicallySecure()
{
return true;
+10
View File
@@ -4,8 +4,12 @@ namespace RobThree\Auth\Providers\Rng;
class HashRNGProvider implements IRNGProvider
{
/** @var string */
private $algorithm;
/**
* @param string $algorithm
*/
public function __construct($algorithm = 'sha256')
{
$algos = array_values(hash_algos());
@@ -15,6 +19,9 @@ class HashRNGProvider implements IRNGProvider
$this->algorithm = $algorithm;
}
/**
* {@inheritdoc}
*/
public function getRandomBytes($bytecount)
{
$result = '';
@@ -26,6 +33,9 @@ class HashRNGProvider implements IRNGProvider
return $result;
}
/**
* {@inheritdoc}
*/
public function isCryptographicallySecure()
{
return false;
+9
View File
@@ -4,6 +4,15 @@ namespace RobThree\Auth\Providers\Rng;
interface IRNGProvider
{
/**
* @param int $bytecount the number of bytes of randomness to return
*
* @return string the random bytes
*/
public function getRandomBytes($bytecount);
/**
* @return bool whether this provider is cryptographically secure
*/
public function isCryptographicallySecure();
}
+10
View File
@@ -4,13 +4,20 @@ namespace RobThree\Auth\Providers\Rng;
class MCryptRNGProvider implements IRNGProvider
{
/** @var int */
private $source;
/**
* @param int $source
*/
public function __construct($source = MCRYPT_DEV_URANDOM)
{
$this->source = $source;
}
/**
* {@inheritdoc}
*/
public function getRandomBytes($bytecount)
{
$result = @mcrypt_create_iv($bytecount, $this->source);
@@ -20,6 +27,9 @@ class MCryptRNGProvider implements IRNGProvider
return $result;
}
/**
* {@inheritdoc}
*/
public function isCryptographicallySecure()
{
return true;
+10
View File
@@ -4,13 +4,20 @@ namespace RobThree\Auth\Providers\Rng;
class OpenSSLRNGProvider implements IRNGProvider
{
/** @var bool */
private $requirestrong;
/**
* @param bool $requirestrong
*/
public function __construct($requirestrong = true)
{
$this->requirestrong = $requirestrong;
}
/**
* {@inheritdoc}
*/
public function getRandomBytes($bytecount)
{
$result = openssl_random_pseudo_bytes($bytecount, $crypto_strong);
@@ -23,6 +30,9 @@ class OpenSSLRNGProvider implements IRNGProvider
return $result;
}
/**
* {@inheritdoc}
*/
public function isCryptographicallySecure()
{
return $this->requirestrong;
+17 -4
View File
@@ -9,17 +9,26 @@ use DateTime;
*/
class HttpTimeProvider implements ITimeProvider
{
/** @var string */
public $url;
public $options;
/** @var string */
public $expectedtimeformat;
/** @var array */
public $options;
/**
* @param string $url
* @param string $expectedtimeformat
* @param array $options
*/
public function __construct($url = 'https://google.com', $expectedtimeformat = 'D, d M Y H:i:s O+', array $options = null)
{
$this->url = $url;
$this->expectedtimeformat = $expectedtimeformat;
$this->options = $options;
if ($this->options === null) {
$this->options = array(
if ($options === null) {
$options = array(
'http' => array(
'method' => 'HEAD',
'follow_location' => false,
@@ -34,8 +43,12 @@ class HttpTimeProvider implements ITimeProvider
)
);
}
$this->options = $options;
}
/**
* {@inheritdoc}
*/
public function getTime()
{
try {
+3
View File
@@ -4,5 +4,8 @@ namespace RobThree\Auth\Providers\Time;
interface ITimeProvider
{
/**
* @return int the current timestamp according to this provider
*/
public function getTime();
}
+13
View File
@@ -7,10 +7,20 @@ namespace RobThree\Auth\Providers\Time;
*/
class NTPTimeProvider implements ITimeProvider
{
/** @var string */
public $host;
/** @var int */
public $port;
/** @var int */
public $timeout;
/**
* @param string $host
* @param int $port
* @param int $timeout
*/
public function __construct($host = 'time.google.com', $port = 123, $timeout = 1)
{
$this->host = $host;
@@ -26,6 +36,9 @@ class NTPTimeProvider implements ITimeProvider
$this->timeout = $timeout;
}
/**
* {@inheritdoc}
*/
public function getTime()
{
try {
+84 -1
View File
@@ -18,18 +18,48 @@ use RobThree\Auth\Providers\Time\NTPTimeProvider;
// Algorithms, digits, period etc. explained: https://github.com/google/google-authenticator/wiki/Key-Uri-Format
class TwoFactorAuth
{
/** @var string */
private $algorithm;
/** @var int */
private $period;
/** @var int */
private $digits;
/** @var string */
private $issuer;
/** @var ?IQRCodeProvider */
private $qrcodeprovider = null;
/** @var ?IRNGProvider */
private $rngprovider = null;
/** @var ?ITimeProvider */
private $timeprovider = null;
/** @var string */
private static $_base32dict = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=';
/** @var array */
private static $_base32;
/** @var array */
private static $_base32lookup = array();
/** @var array */
private static $_supportedalgos = array('sha1', 'sha256', 'sha512', 'md5');
/**
* @param ?string $issuer
* @param int $digits
* @param int $period
* @param string $algorithm
* @param ?IQRCodeProvider $qrcodeprovider
* @param ?IRNGProvider $rngprovider
* @param ?ITimeProvider $timeprovider
*/
public function __construct($issuer = null, $digits = 6, $period = 30, $algorithm = 'sha1', IQRCodeProvider $qrcodeprovider = null, IRNGProvider $rngprovider = null, ITimeProvider $timeprovider = null)
{
$this->issuer = $issuer;
@@ -58,6 +88,11 @@ class TwoFactorAuth
/**
* Create a new secret
*
* @param int $bits
* @param bool $requirecryptosecure
*
* @return string
*/
public function createSecret($bits = 80, $requirecryptosecure = true)
{
@@ -76,6 +111,11 @@ class TwoFactorAuth
/**
* Calculate the code with given secret and point in time
*
* @param string $secret
* @param ?int $time
*
* @return string
*/
public function getCode($secret, $time = null)
{
@@ -92,6 +132,14 @@ class TwoFactorAuth
/**
* Check if the code is correct. This will accept codes starting from ($discrepancy * $period) sec ago to ($discrepancy * period) sec from now
*
* @param string $secret
* @param string $code
* @param int $discrepancy
* @param ?int $time
* @param int $timeslice
*
* @return bool
*/
public function verifyCode($secret, $code, $discrepancy = 1, $time = null, &$timeslice = 0)
{
@@ -114,6 +162,11 @@ class TwoFactorAuth
/**
* Timing-attack safe comparison of 2 codes (see http://blog.ircmaxell.com/2014/11/its-all-about-time.html)
*
* @param string $safe
* @param string $user
*
* @return bool
*/
private function codeEquals($safe, $user)
{
@@ -134,6 +187,12 @@ class TwoFactorAuth
/**
* Get data-uri of QRCode
*
* @param string $label
* @param string $secret
* @param mixed $size
*
* @return string
*/
public function getQRCodeImageAsDataUri($label, $secret, $size = 200)
{
@@ -150,6 +209,10 @@ class TwoFactorAuth
/**
* Compare default timeprovider with specified timeproviders and ensure the time is within the specified number of seconds (leniency)
* @param ?array $timeproviders
* @param int $leniency
*
* @return void
*/
public function ensureCorrectTime(array $timeproviders = null, $leniency = 5)
{
@@ -176,11 +239,22 @@ class TwoFactorAuth
}
}
private function getTime($time)
/**
* @param ?int $time
*
* @return int
*/
private function getTime($time = null)
{
return ($time === null) ? $this->getTimeProvider()->getTime() : $time;
}
/**
* @param int $time
* @param int $offset
*
* @return int
*/
private function getTimeSlice($time = null, $offset = 0)
{
return (int)floor($time / $this->period) + ($offset * $this->period);
@@ -188,6 +262,11 @@ class TwoFactorAuth
/**
* Builds a string to be encoded in a QR code
*
* @param string $label
* @param string $secret
*
* @return string
*/
public function getQRText($label, $secret)
{
@@ -199,6 +278,10 @@ class TwoFactorAuth
. '&digits=' . intval($this->digits);
}
/**
* @param string $value
* @return string
*/
private function base32Decode($value)
{
if (strlen($value) == 0) {
+2
View File
@@ -9,6 +9,8 @@ trait MightNotMakeAssertions
*
* It has to be named something that doesn't collide with existing
* TestCase methods as we can't support PHP return types right now
*
* @return void
*/
public function noAssertionsMade()
{
@@ -8,6 +8,11 @@ use RobThree\Auth\TwoFactorAuthException;
class IQRCodeProviderTest extends TestCase
{
/**
* @param string $datauri
*
* @return null|array
*/
private function DecodeDataUri($datauri)
{
if (preg_match('/data:(?P<mimetype>[\w\.\-\/]+);(?P<encoding>\w+),(?P<data>.*)/', $datauri, $m) === 1) {
@@ -21,6 +26,9 @@ class IQRCodeProviderTest extends TestCase
return null;
}
/**
* @return void
*/
public function testTotpUriIsCorrect()
{
$qr = new TestQrProvider();
@@ -32,6 +40,9 @@ class IQRCodeProviderTest extends TestCase
$this->assertEquals('otpauth://totp/Test%26Label?secret=VMR466AB62ZBOKHE&issuer=Test%26Issuer&period=30&algorithm=SHA1&digits=6@200', $data['data']);
}
/**
* @return void
*/
public function testGetQRCodeImageAsDataUriThrowsOnInvalidSize()
{
$qr = new TestQrProvider();
+6
View File
@@ -6,11 +6,17 @@ use RobThree\Auth\Providers\Qr\IQRCodeProvider;
class TestQrProvider implements IQRCodeProvider
{
/**
* {@inheritdoc}
*/
public function getQRCodeImage($qrtext, $size)
{
return $qrtext . '@' . $size;
}
/**
* {@inheritdoc}
*/
public function getMimeType()
{
return 'test/test';
@@ -12,6 +12,8 @@ class CSRNGProviderTest extends TestCase
/**
* @requires function random_bytes
*
* @return void
*/
public function testCSRNGProvidersReturnExpectedNumberOfBytes()
{
@@ -9,6 +9,9 @@ class HashRNGProviderTest extends TestCase
{
use NeedsRngLengths;
/**
* @return void
*/
public function testHashRNGProvidersReturnExpectedNumberOfBytes()
{
$rng = new HashRNGProvider();
+12
View File
@@ -8,6 +8,9 @@ use RobThree\Auth\TwoFactorAuthException;
class IRNGProviderTest extends TestCase
{
/**
* @return void
*/
public function testCreateSecretThrowsOnInsecureRNGProvider()
{
$rng = new TestRNGProvider();
@@ -18,6 +21,9 @@ class IRNGProviderTest extends TestCase
$tfa->createSecret();
}
/**
* @return void
*/
public function testCreateSecretOverrideSecureDoesNotThrowOnInsecureRNG()
{
$rng = new TestRNGProvider();
@@ -26,6 +32,9 @@ class IRNGProviderTest extends TestCase
$this->assertEquals('ABCDEFGHIJKLMNOP', $tfa->createSecret(80, false));
}
/**
* @return void
*/
public function testCreateSecretDoesNotThrowOnSecureRNGProvider()
{
$rng = new TestRNGProvider(true);
@@ -34,6 +43,9 @@ class IRNGProviderTest extends TestCase
$this->assertEquals('ABCDEFGHIJKLMNOP', $tfa->createSecret());
}
/**
* @return void
*/
public function testCreateSecretGeneratesDesiredAmountOfEntropy()
{
$rng = new TestRNGProvider(true);
@@ -12,6 +12,8 @@ class MCryptRNGProviderTest extends TestCase
/**
* @requires function mcrypt_create_iv
*
* @return void
*/
public function testMCryptRNGProvidersReturnExpectedNumberOfBytes()
{
+1
View File
@@ -4,5 +4,6 @@ namespace Tests\Providers\Rng;
trait NeedsRngLengths
{
/** @var array */
protected $rngTestLengths = array(1, 16, 32, 256);
}
@@ -9,6 +9,9 @@ class OpenSSLRNGProviderTest extends TestCase
{
use NeedsRngLengths;
/**
* @return void
*/
public function testStrongOpenSSLRNGProvidersReturnExpectedNumberOfBytes()
{
$rng = new OpenSSLRNGProvider(true);
@@ -19,6 +22,9 @@ class OpenSSLRNGProviderTest extends TestCase
$this->assertTrue($rng->isCryptographicallySecure());
}
/**
* @return void
*/
public function testNonStrongOpenSSLRNGProvidersReturnExpectedNumberOfBytes()
{
$rng = new OpenSSLRNGProvider(false);
+10
View File
@@ -6,13 +6,20 @@ use RobThree\Auth\Providers\Rng\IRNGProvider;
class TestRNGProvider implements IRNGProvider
{
/** @var bool */
private $isSecure;
/**
* @param bool $isSecure whether this provider is cryptographically secure
*/
function __construct($isSecure = false)
{
$this->isSecure = $isSecure;
}
/**
* {@inheritdoc}
*/
public function getRandomBytes($bytecount)
{
$result = '';
@@ -24,6 +31,9 @@ class TestRNGProvider implements IRNGProvider
return $result;
}
/**
* {@inheritdoc}
*/
public function isCryptographicallySecure()
{
return $this->isSecure;
@@ -11,6 +11,9 @@ class ITimeProviderTest extends TestCase
{
use MightNotMakeAssertions;
/**
* @return void
*/
public function testEnsureCorrectTimeDoesNotThrowForCorrectTime()
{
$tpr1 = new TestTimeProvider(123);
@@ -22,6 +25,9 @@ class ITimeProviderTest extends TestCase
$this->noAssertionsMade();
}
/**
* @return void
*/
public function testEnsureCorrectTimeThrowsOnIncorrectTime()
{
$tpr1 = new TestTimeProvider(123);
@@ -34,6 +40,9 @@ class ITimeProviderTest extends TestCase
$tfa->ensureCorrectTime(array($tpr2), 0); // We force a leniency of 0, 124-123 = 1 so this should throw
}
/**
* @return void
*/
public function testEnsureDefaultTimeProviderReturnsCorrectTime()
{
$tfa = new TwoFactorAuth('Test', 6, 30, 'sha1');
@@ -6,13 +6,20 @@ use RobThree\Auth\Providers\Time\ITimeProvider;
class TestTimeProvider implements ITimeProvider
{
/** @var int */
private $time;
/**
* @param int $time
*/
function __construct($time)
{
$this->time = $time;
}
/**
* {@inheritdoc}
*/
public function getTime()
{
return $this->time;
+42
View File
@@ -10,6 +10,9 @@ class TwoFactorAuthTest extends TestCase
{
use MightNotMakeAssertions;
/**
* @return void
*/
public function testConstructorThrowsOnInvalidDigits()
{
$this->expectException(TwoFactorAuthException::class);
@@ -17,6 +20,9 @@ class TwoFactorAuthTest extends TestCase
new TwoFactorAuth('Test', 0);
}
/**
* @return void
*/
public function testConstructorThrowsOnInvalidPeriod()
{
$this->expectException(TwoFactorAuthException::class);
@@ -24,6 +30,9 @@ class TwoFactorAuthTest extends TestCase
new TwoFactorAuth('Test', 6, 0);
}
/**
* @return void
*/
public function testConstructorThrowsOnInvalidAlgorithm()
{
$this->expectException(TwoFactorAuthException::class);
@@ -31,6 +40,9 @@ class TwoFactorAuthTest extends TestCase
new TwoFactorAuth('Test', 6, 30, 'xxx');
}
/**
* @return void
*/
public function testGetCodeReturnsCorrectResults()
{
$tfa = new TwoFactorAuth('Test');
@@ -38,6 +50,9 @@ class TwoFactorAuthTest extends TestCase
$this->assertEquals('538532', $tfa->getCode('VMR466AB62ZBOKHE', 0));
}
/**
* @return void
*/
public function testEnsureAllTimeProvidersReturnCorrectTime()
{
$tfa = new TwoFactorAuth('Test', 6, 30, 'sha1');
@@ -51,6 +66,9 @@ class TwoFactorAuthTest extends TestCase
$this->noAssertionsMade();
}
/**
* @return void
*/
public function testVerifyCodeWorksCorrectly()
{
$tfa = new TwoFactorAuth('Test', 6, 30);
@@ -70,6 +88,9 @@ class TwoFactorAuthTest extends TestCase
$this->assertTrue($tfa->verifyCode('VMR466AB62ZBOKHE', '543160', 2, 1426847205 - 65)); //Test discrepancy
}
/**
* @return void
*/
public function testVerifyCorrectTimeSliceIsReturned()
{
$tfa = new TwoFactorAuth('Test', 6, 30);
@@ -96,6 +117,9 @@ class TwoFactorAuthTest extends TestCase
$this->assertEquals(0, $timeslice8);
}
/**
* @return void
*/
public function testGetCodeThrowsOnInvalidBase32String1()
{
$tfa = new TwoFactorAuth('Test');
@@ -105,6 +129,9 @@ class TwoFactorAuthTest extends TestCase
$tfa->getCode('FOO1BAR8BAZ9'); //1, 8 & 9 are invalid chars
}
/**
* @return void
*/
public function testGetCodeThrowsOnInvalidBase32String2()
{
$tfa = new TwoFactorAuth('Test');
@@ -114,6 +141,9 @@ class TwoFactorAuthTest extends TestCase
$tfa->getCode('mzxw6==='); //Lowercase
}
/**
* @return void
*/
public function testKnownBase32DecodeTestVectors()
{
// We usually don't test internals (e.g. privates) but since we rely heavily on base32 decoding and don't want
@@ -142,6 +172,9 @@ class TwoFactorAuthTest extends TestCase
$this->assertEquals('foobar', $method->invoke($tfa, 'MZXW6YTBOI======'));
}
/**
* @return void
*/
public function testKnownBase32DecodeUnpaddedTestVectors()
{
// See testKnownBase32DecodeTestVectors() for the rationale behind testing the private base32Decode() method.
@@ -163,6 +196,9 @@ class TwoFactorAuthTest extends TestCase
$this->assertEquals('foobar', $method->invoke($tfa, 'MZXW6YTBOI'));
}
/**
* @return void
*/
public function testKnownTestVectors_sha1()
{
//Known test vectors for SHA1: https://tools.ietf.org/html/rfc6238#page-15
@@ -176,6 +212,9 @@ class TwoFactorAuthTest extends TestCase
$this->assertEquals('65353130', $tfa->getCode($secret, 20000000000));
}
/**
* @return void
*/
public function testKnownTestVectors_sha256()
{
//Known test vectors for SHA256: https://tools.ietf.org/html/rfc6238#page-15
@@ -189,6 +228,9 @@ class TwoFactorAuthTest extends TestCase
$this->assertEquals('77737706', $tfa->getCode($secret, 20000000000));
}
/**
* @return void
*/
public function testKnownTestVectors_sha512()
{
//Known test vectors for SHA512: https://tools.ietf.org/html/rfc6238#page-15