<?php
class Blake2bTest extends PHPUnit_Framework_TestCase
{
/**
* @before
*/
public function before()
{
ParagonIE_Sodium_Compat::$disableFallbackForUnitTests = true;
}
/**
* @covers ParagonIE_Sodium_Compat::crypto_generichash()
*
* @throws SodiumException
* @throws TypeError
*/
public function testGenericHash()
{
$this->assertSame(
'df654812bac492663825520ba2f6e67cf5ca5bdc13d4e7507a98cc4c2fcc3ad8',
ParagonIE_Sodium_Core_Util::bin2hex(
ParagonIE_Sodium_Compat::crypto_generichash('Paragon Initiative Enterprises, LLC')
),
'Chosen input.'
);
}
/**
* @throws SodiumException
*/
public function testPersonalizedState()
{
$exp = ParagonIE_Sodium_Core_Util::hex2bin(
'48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5e4e0d0cf4b636b35260e0d1fbf0e60ab' .
'5e8c73cdcdbbb17e4a164a2329a9d23a0000000000000000000000000000000000000000000000000000000000000000' .
'000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' .
'000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' .
'000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' .
'000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' .
'000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' .
'000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
);
$k = '';
$salt = '5b6b41ed9b343fe0';
$personal = '5126fb2a37400d2a';
for ($h = 0; $h < 64; ++$h) {
$k[$h] = ParagonIE_Sodium_Core_Util::intToChr($h);
}
$state = ParagonIE_Sodium_Compat::crypto_generichash_init_salt_personal('', 64, $salt, $personal);
// Chop off last 17 bytes if present because they'll throw off tests:
$a = ParagonIE_Sodium_Core_Util::substr($state, 0, 361);
$b = ParagonIE_Sodium_Core_Util::substr($exp, 0, 361);
$this->assertEquals(
ParagonIE_Sodium_Core_Util::bin2hex($b),
ParagonIE_Sodium_Core_Util::bin2hex($a),
'Initialized value is incorrect'
);
$in = '';
for ($i = 0; $i < 64; ++$i) {
$in .= ParagonIE_Sodium_Core_Util::intToChr($i);
}
ParagonIE_Sodium_Compat::crypto_generichash_update($state, $in);
$exp2 = ParagonIE_Sodium_Core_Util::hex2bin(
'48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5e4e0d0cf4b636b35260e0d1fbf0e60ab' .
'5e8c73cdcdbbb17e4a164a2329a9d23a0000000000000000000000000000000000000000000000000000000000000000' .
'000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f' .
'303132333435363738393a3b3c3d3e3f0000000000000000000000000000000000000000000000000000000000000000' .
'000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' .
'000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' .
'000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' .
'000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000'
);
// Chop off last 17 bytes if present because they'll throw off tests:
$a = ParagonIE_Sodium_Core_Util::substr($state, 0, 361);
$b = ParagonIE_Sodium_Core_Util::substr($exp2, 0, 361);
$this->assertEquals(
ParagonIE_Sodium_Core_Util::bin2hex($b),
ParagonIE_Sodium_Core_Util::bin2hex($a),
'Updated value is incorrect'
);
}
/**
* @covers ParagonIE_Sodium_Compat::crypto_generichash()
*
* @throws SodiumException
* @throws TypeError
*/
public function testGenericHashSaltPersonal()
{
$outputs = array(
'ba',
'6139',
'3a1666',
'5797e9d0',
'834a26efe6',
'd7e9e862bbce',
'40d8b84c374750',
'276789189244cf04',
'16f73ffe0673cc9992',
'b3835bfaf6eb71d94078',
'8c624e844d34f4a59f34cc',
'e0a394962413ad09975df3cf',
'47f043c3aacb501f97e0458ae3',
'b4a11f2fb72a7e6f96fdacf98d49',
'f434079e9adeb244047cb6855f9854',
'5fbe885c4b2d4e0d78dc5905622a277a',
'e262ba3e2ab76efdf83513108e3b987d1b',
'add93dde78d32e77bc039c34a49043f19d26',
'093842ac10e2eb1237ddc9ca9e7990cf397772',
'09e7f6a0e2ea4888f1dbf6562effd1561c65029c',
'bd33a9ec914f5b81864a49184338e4062d6c6b2b2e',
'8dc46295235d94f5881d429a5ad47f9db9e35cf8c6b3',
'ba5df554dca7ac1cba4889fa88adf3070fbf4ab5d187b5',
'1ff84715e71c66214d271d421395fb6166db97b1d47ed697',
'75a0d227c70549f5b0c933b7b21f151355bd47e04b6085c91f',
'a32a5c9439a0fa771dcbe7f338b5dcef62a754edc4952614d6f0',
'53a87de519cdcc7f64730d58bce6baaf7b44c5c428a4611a208ad4',
'5e5ad8f0c4f083f9b7a5154d9c0dfd0f3d2fce94cf54fc215450314a',
'9c76b9e63c77e6564b1e5111c2fb140046e1e5a4f900a7cfc2bac3fcfa',
'bb919251ca310eb9b994e5d7883bc9fa2144b59b8d5d940677b7130ac777',
'faa492a66f08ef0c7adb868fcb7b523aedd35b8ff1414bd1d554794f144474',
'9b273ebe335540b87be899abe169389ed61ed262c3a0a16e4998bbf752f0bee3',
'1e0070b92429c151b33bdd1bb4430a0e650a3dfc94d404054e93c8568330ecc505',
'e3b64149f1b76231686d592d1d4af984ce2826ba03c2224a92f95f9526130ce4eb' .
'40',
'5f8e378120b73db9eefa65ddcdcdcb4acd8046c31a5e47f298caa400937d5623f1' .
'394b',
'74c757a4165a1782c933e587353a9fd8f6d7bf26b7f51b52c542747030bfb3d560' .
'c2e5c2',
'2d5ee85cc238b923806dd98db18919d1924f2340ec88917d4ce1799cbfd5f2cb9d' .
'f99db2e1',
'c93ff727e6f9822efec0a77eed0025c0eff19127bf8746b7c71c2a098f57cef02f' .
'ebb86a1e6c',
'adfb6d7ba13779a5dd1bbf268e400f4156f0f5c9d5b670ff539e1d9c1a63373416' .
'f3001f338407',
'3a6900e58a448887d77c5911e4bdde620e64f25b2d71723fa60f7cb3efa7c320b6' .
'153bdbc3287949',
'413eb0fd379b32dd88e82242a87cc58ce3e64c72352387a4c70f92ee5c8d23fa7e' .
'cd86f6df170a32d2',
'92d0d3cacc3e25628caf6f2c4cd50d25d154ac45098f531d690230b859f37cfe08' .
'9eb169f76bba72a3ff',
'92f6ccc11a9a3bee520b17e0cddc4550c0e9cf47ddd9a6161284259ffb161c1d06' .
'75b505cb1066872768e8',
'a3cd675804e6be7f120138a9eaadcd56bb7763d1c046e87fe0d358c8276b0d2462' .
'1f46c60b46e397933b75b4',
'304a1af53cbdd6486b8419d1ebd5e9528c540d8dc46a10be49067f46a061722957' .
'7015d776783f702b2954df43',
'd8a6358970446453ac0c82c758644ab68989b5b4f06f9768807ce0c5f2a0dbac1e' .
'8450f4e3a02deecf7b54b6a45d',
'1264b8dee9ac4aa8de69a43ada95cc95f20230f33836d4a1db8c2466ab38361686' .
'e5ac282025ccc2e0f6a1cd98a4dd',
'7eed787abaa7f4e8b8aa3090f0676201cfbaaf350899661cdd5216ac0b5cd87444' .
'3f5c0688ffd7ca1ccbfe1ca7e1a3f5',
'8907f0218585167962a8e8213559a643dd03c2bf1a7a5ad3e3bc5f88c0ff1532ee' .
'8cd29880e7e0e68da22a5798aef27cc5',
'12dea17b0733e5060751b1115e10c3d4b2f4583bcd009d9f1f42ec23d4a6a0df11' .
'85d3abbdbe86de08569e70583d6de1c1fe',
'8ff75e91f1de547dc3a25472db2f51f5910a290c449603da54207b5e39bd735d24' .
'0ec913b52df90709b5d29357971d6c341452',
'4a3b16b12400f38e74778efc3a4caa52ec6fdf6b0180a5bfac9189e52e162c10e8' .
'911a54ab33e2b389ee1949e58edaa119e2b2b9',
'c9943e7186fdc9bbfa1d7087fa7086babe6fcf95a6196d1772187854071304e2f1' .
'fff39e6e6f48f76addb16d5c00249e0523aac91f',
'0297f16fdd34add9cc87b4adf816525b590ba08ac733c43f8d225d194df4f9c83b' .
'4dce617be51e25b5f6c80dff249f27c707de20e422',
'576bb891eab9930998e2e73b5d0498e3c5f040f8dec9397a8c7a622c17de01fee7' .
'cc936e3bd4de1f7fd8b31dea9e70c65462bbb5dc7b50',
'9416a57ae7c8c51c6e008f940fe06d8ebc02c350c19a2f71583a6d260b085670d7' .
'3a95248fef0f4cae5292ba7db1189a7cd9c51122ba7913',
'ea644b9051cca5eee8868a553e3f0f4e14739e1555474151156e10578256b288a2' .
'33870dd43a380765400ea446df7f452c1e03a9e5b6731256',
'f99cc1603de221abc1ecb1a7eb4bbf06e99561d1cc5541d8d601bae2b1dd3cbe44' .
'8ac276667f26de5e269183a09f7deaf35d33174b3cc8ad4aa2',
'ee2be1ec57fdac23f89402a534177eca0f4b982a4ed2c2e900b6a79e1f47a2d023' .
'eff2e647baf4f4c0da3a28d08a44bc780516974074e2523e6651',
'9cda001868949a2bad96c5b3950a8315e6e5214d0b54dcd596280565d351806ef2' .
'2cf3053f63623da72fcad9afa3896641658632334c9ec4f644c984',
'c6d6722a916651a8671383d8260873347d9c248696b4cb3dac4dea9ba57ed97112' .
'7cb18e44211d7e14177ace248b3c6e0785356ee261ebdc6ef0faf143',
'5dd258a3e7505bc6b9776b0df25676a1c19e2c8258c7b5f2e361423523d96299eb' .
'6827bc7c27e7bca2d2b59d717c2ebcb05e6dcaa32289d96fae9a4077ef',
'19c14de35fe19c92cc0e624280e4136355d4cfa9a0a98b090c4b06f56650219207' .
'25852ff1f566b0c8c37157b25fb9f947a2e70b40577a17860a0732c170ac',
'5fcdcc02be7714a0dbc77df498bf999ea9225d564adca1c121c9af03af92cac817' .
'7b9b4a86bcc47c79aa32aac58a3fef967b2132e9352d4613fe890beed2571b'
);
$salt = '5b6b41ed9b343fe0';
$personal = '5126fb2a37400d2a';
$key = '';
for ($h = 0; $h < 64; ++$h) {
$key .= ParagonIE_Sodium_Core_Util::intToChr($h);
}
$in = '';
for ($i = 0; $i < 64; ++$i) {
$in .= ParagonIE_Sodium_Core_Util::intToChr($i);
$state = ParagonIE_Sodium_Compat::crypto_generichash_init_salt_personal(
ParagonIE_Sodium_Core_Util::substr((string) $key, 0, $i + 1),
$i + 1,
$salt,
$personal
);
if ($i === 1) {
$exp0 = '0acbbdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5e4e0d0cf4b636b35260e0d1fbf0e60ab5e8c73cdcdbbb17e4a164a2329a9d23a0000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000';
$this->assertSame($exp0, bin2hex($state), 'state before update');
}
ParagonIE_Sodium_Compat::crypto_generichash_update($state, ParagonIE_Sodium_Core_Util::substr($in, 0, $i));
if ($i === 1) {
$exp1 = '0acbbdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5e4e0d0cf4b636b35260e0d1fbf0e60ab5e8c73cdcdbbb17e4a164a2329a9d23a0000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008100000000000000000000000000000000000000000000000000000000000000';
$this->assertSame($exp1, bin2hex($state), 'state after update');
}
$out = ParagonIE_Sodium_Compat::crypto_generichash_final($state, $i + 1);
$this->assertEquals(
$outputs[$i],
ParagonIE_Sodium_Core_Util::bin2hex($out),
'BLAKE2b Personal (i = ' . $i . ' failed)'
);
}
}
/**
* @covers ParagonIE_Sodium_Core_BLAKE2b::update()
* @throws SodiumException
* @throws TypeError
*/
public function testGenericHashUpdate()
{
for ($h = 8; $h < 15; ++$h) {
$hbuf = new SplFixedArray(1 << $h);
for ($i = 0; $i < (1 << $h); ++$i) {
$hbuf[$i] = $i & 0xff;
}
$buf = new SplFixedArray(1 << ($h + 1));
for ($i = 0; $i < (1 << ($h + 1)); ++$i) {
$buf[$i] = $i & 0xff;
}
$hbufStr = ParagonIE_Sodium_Core_Util::intArrayToString($hbuf->toArray());
$this->assertSame(
ParagonIE_Sodium_Core_Util::intArrayToString($buf->toArray()),
$hbufStr . $hbufStr
);
if (PHP_INT_SIZE === 4) {
$exp = ParagonIE_Sodium_Core32_BLAKE2b::init();
ParagonIE_Sodium_Core32_BLAKE2b::update($exp, $hbuf, (1 << $h));
ParagonIE_Sodium_Core32_BLAKE2b::update($exp, $hbuf, (1 << $h));
$ctx = ParagonIE_Sodium_Core32_BLAKE2b::init();
ParagonIE_Sodium_Core32_BLAKE2b::update($ctx, $buf, (1 << ($h + 1)));
} else {
$exp = ParagonIE_Sodium_Core_BLAKE2b::init();
ParagonIE_Sodium_Core_BLAKE2b::update($exp, $hbuf, (1 << $h));
ParagonIE_Sodium_Core_BLAKE2b::update($exp, $hbuf, (1 << $h));
$ctx = ParagonIE_Sodium_Core_BLAKE2b::init();
ParagonIE_Sodium_Core_BLAKE2b::update($ctx, $buf, (1 << ($h + 1)));
}
for ($j = 0; $j < 5; ++$j) {
$this->assertEquals($exp[$j], $ctx[$j], 'element ' . $j);
}
if (PHP_INT_SIZE === 4) {
$this->assertSame(
bin2hex(ParagonIE_Sodium_Core32_BLAKE2b::contextToString($exp)),
bin2hex(ParagonIE_Sodium_Core32_BLAKE2b::contextToString($ctx)),
'h = ' . $h
);
} else {
$this->assertSame(
bin2hex(ParagonIE_Sodium_Core_BLAKE2b::contextToString($exp)),
bin2hex(ParagonIE_Sodium_Core_BLAKE2b::contextToString($ctx)),
'h = ' . $h
);
}
}
}
/**
* @covers ParagonIE_Sodium_Core_BLAKE2b::increment_counter()
*/
public function testCounter()
{
if (PHP_INT_SIZE === 4) {
$this->markTestSkipped("Ignored in 32-bit");
}
$ctx = ParagonIE_Sodium_Core_BLAKE2b::init(null, 32);
ParagonIE_Sodium_Core_BLAKE2b::increment_counter($ctx, 1);
$this->assertEquals(1, $ctx[1][0][1]);
$this->assertEquals(0, $ctx[1][0][0]);
ParagonIE_Sodium_Core_BLAKE2b::increment_counter($ctx, 1);
$this->assertEquals(2, $ctx[1][0][1]);
$this->assertEquals(0, $ctx[1][0][0]);
ParagonIE_Sodium_Core_BLAKE2b::increment_counter($ctx, 1024);
$this->assertEquals(1026, $ctx[1][0][1]);
$this->assertEquals(0, $ctx[1][0][0]);
for ($i = 0; $i < 4; ++$i) {
ParagonIE_Sodium_Core_BLAKE2b::increment_counter($ctx, 1 << 30);
}
$this->assertEquals(1026, $ctx[1][0][1]);
$this->assertEquals(1, $ctx[1][0][0]);
}
/**
* @covers ParagonIE_Sodium_Core32_BLAKE2b::increment_counter()
*/
public function testCounter32()
{
if (PHP_INT_SIZE === 8) {
$this->markTestSkipped("32-bit only");
}
$ctx = ParagonIE_Sodium_Core32_BLAKE2b::init(null, 32);
ParagonIE_Sodium_Core32_BLAKE2b::increment_counter($ctx, 1);
$this->assertEquals(1, $ctx[1][0]->toInt());
$this->assertEquals(0, $ctx[1][1]->toInt());
ParagonIE_Sodium_Core32_BLAKE2b::increment_counter($ctx, 1);
$this->assertEquals(2, $ctx[1][0]->toInt());
$this->assertEquals(0, $ctx[1][1]->toInt());
ParagonIE_Sodium_Core32_BLAKE2b::increment_counter($ctx, 1024);
$this->assertEquals(1026, $ctx[1][0]->toInt());
$this->assertEquals(0, $ctx[1][1]->toInt());
for ($i = 0; $i < 4; ++$i) {
ParagonIE_Sodium_Core32_BLAKE2b::increment_counter($ctx, 1 << 30);
}
/** @var ParagonIE_Sodium_Core32_Int64 $c */
$c = $ctx[1][0]->toArray();
$this->assertEquals(1026, $c[1]);
$this->assertEquals(1, $c[0]);
}
/**
* Make sure our 'context' string is consistent.
*
* @covers ParagonIE_Sodium_Core_BLAKE2b::init()
* @covers ParagonIE_Sodium_Core_BLAKE2b::update()
* @covers ParagonIE_Sodium_Core_BLAKE2b::contextToString()
* @covers ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray()
*/
public function testContext()
{
$ctxA = ParagonIE_Sodium_Compat::crypto_generichash_init();
if (PHP_INT_SIZE === 4) {
$ctxB = ParagonIE_Sodium_Core32_BLAKE2b::init(null, 32);
} else {
$ctxB = ParagonIE_Sodium_Core_BLAKE2b::init(null, 32);
}
$chunks = array(
'Paragon Initiative ',
'Enterprises, LLC',
str_repeat("\x7e", 128),
str_repeat("\x4d", 256),
str_repeat("\x2f", 128),
str_repeat("\x2e", 128),
str_repeat("0", 128),
str_repeat("\x4e", 64),
str_repeat("\x4f", 257),
str_repeat("\x0a", 511)
);
foreach ($chunks as $i => $chk) {
ParagonIE_Sodium_Compat::crypto_generichash_update($ctxA, $chk);
if (PHP_INT_SIZE === 4) {
$chunk = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($chk);
ParagonIE_Sodium_Core32_BLAKE2b::update(
$ctxB,
$chunk,
$chunk->count()
);
} else {
$chunk = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($chk);
ParagonIE_Sodium_Core_BLAKE2b::update(
$ctxB,
$chunk,
$chunk->count()
);
}
/** @var string $ctxStrB */
if (PHP_INT_SIZE === 4) {
$ctxStrB = ParagonIE_Sodium_Core32_BLAKE2b::contextToString($ctxB);
} else {
$ctxStrB = ParagonIE_Sodium_Core_BLAKE2b::contextToString($ctxB);
}
$this->assertEquals(
ParagonIE_Sodium_Core_Util::bin2hex(
ParagonIE_Sodium_Core_Util::substr($ctxA, 0, 64)
),
ParagonIE_Sodium_Core_Util::bin2hex(
ParagonIE_Sodium_Core_Util::substr($ctxStrB, 0, 64)
),
'chunk #' . ($i + 1) . ' - 0'
);
$this->assertEquals(
ParagonIE_Sodium_Core_Util::bin2hex(
ParagonIE_Sodium_Core_Util::substr($ctxA, 64, 32)
),
ParagonIE_Sodium_Core_Util::bin2hex(
ParagonIE_Sodium_Core_Util::substr($ctxStrB, 64, 32)
),
'chunk #' . ($i + 1) . ' - 1'
);
$this->assertEquals(
ParagonIE_Sodium_Core_Util::bin2hex(
ParagonIE_Sodium_Core_Util::substr($ctxA, 96, 256)
),
ParagonIE_Sodium_Core_Util::bin2hex(
ParagonIE_Sodium_Core_Util::substr($ctxStrB, 96, 256)
),
'chunk #' . ($i + 1) . ' - 2'
);
}
}
/**
* @covers ParagonIE_Sodium_Compat::crypto_generichash_init()
* @covers ParagonIE_Sodium_Compat::crypto_generichash_update()
* @covers ParagonIE_Sodium_Compat::crypto_generichash_final()
* @covers ParagonIE_Sodium_Core_BLAKE2b::init()
* @covers ParagonIE_Sodium_Core_BLAKE2b::update()
* @covers ParagonIE_Sodium_Core_BLAKE2b::finish()
*
* @throws SodiumException
* @throws Exception
*/
public function testGenericHashStream()
{
$ctx = ParagonIE_Sodium_Compat::crypto_generichash_init();
$this->assertSame(
'28c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
bin2hex($ctx),
'Context initialization is incorrect.'
);
ParagonIE_Sodium_Compat::crypto_generichash_update($ctx, 'Paragon Initiative ');
ParagonIE_Sodium_Compat::crypto_generichash_update($ctx, 'Enterprises, LLC');
$this->assertSame(
'df654812bac492663825520ba2f6e67cf5ca5bdc13d4e7507a98cc4c2fcc3ad8',
bin2hex(ParagonIE_Sodium_Compat::crypto_generichash_final($ctx)),
'Chosen input.'
);
for ($i = 1; $i < 9; ++$i) {
$data = random_bytes(1 << $i);
$data2 = random_bytes(1 << $i);
// Hash 1
$hash = ParagonIE_Sodium_Compat::crypto_generichash($data . $data2);
// Hash 2
$ctx = ParagonIE_Sodium_Compat::crypto_generichash_init(null, 32);
ParagonIE_Sodium_Compat::crypto_generichash_update($ctx, $data);
ParagonIE_Sodium_Compat::crypto_generichash_update($ctx, $data2);
$hash2 = ParagonIE_Sodium_Compat::crypto_generichash_final($ctx);
// Hash 3
$out = new SplFixedArray(32);
if (PHP_INT_SIZE === 4) {
$d1s = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($data);
$d2s = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($data2);
$ctx = ParagonIE_Sodium_Core32_BLAKE2b::init(null, 32);
ParagonIE_Sodium_Core32_BLAKE2b::update($ctx, $d1s, $d1s->count());
ParagonIE_Sodium_Core32_BLAKE2b::update($ctx, $d2s, $d2s->count());
ParagonIE_Sodium_Core32_BLAKE2b::finish($ctx, $out);
$hash3 = ParagonIE_Sodium_Core32_BLAKE2b::SplFixedArrayToString($out);
} else {
$d1s = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($data);
$d2s = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($data2);
$ctx = ParagonIE_Sodium_Core_BLAKE2b::init(null, 32);
ParagonIE_Sodium_Core_BLAKE2b::update($ctx, $d1s, $d1s->count());
ParagonIE_Sodium_Core_BLAKE2b::update($ctx, $d2s, $d2s->count());
ParagonIE_Sodium_Core_BLAKE2b::finish($ctx, $out);
$hash3 = ParagonIE_Sodium_Core_BLAKE2b::SplFixedArrayToString($out);
}
$this->assertSame(bin2hex($hash), bin2hex($hash3), 'Generichash streaming is failing (' . $i . ') a');
$this->assertSame(bin2hex($hash2), bin2hex($hash3), 'Generichash streaming is failing (' . $i . ') b');
$this->assertSame(bin2hex($hash2), bin2hex($hash), 'Generichash streaming is failing (' . $i . ') c');
}
$data = random_bytes(1 << $i);
$data2 = random_bytes(1 << $i);
$k = random_bytes(32);
// Hash 1
$hash = ParagonIE_Sodium_Compat::crypto_generichash($data . $data2, $k);
// Hash 2
$ctx = ParagonIE_Sodium_Compat::crypto_generichash_init($k, 32);
ParagonIE_Sodium_Compat::crypto_generichash_update($ctx, $data);
ParagonIE_Sodium_Compat::crypto_generichash_update($ctx, $data2);
$hash2 = ParagonIE_Sodium_Compat::crypto_generichash_final($ctx);
// Hash 3
$out = new SplFixedArray(32);
if (PHP_INT_SIZE === 4) {
$d1s = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($data);
$d2s = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($data2);
$key = ParagonIE_Sodium_Core32_BLAKE2b::stringToSplFixedArray($k);
$ctx = ParagonIE_Sodium_Core32_BLAKE2b::init($key, 32);
ParagonIE_Sodium_Core32_BLAKE2b::update($ctx, $d1s, $d1s->count());
ParagonIE_Sodium_Core32_BLAKE2b::update($ctx, $d2s, $d2s->count());
ParagonIE_Sodium_Core32_BLAKE2b::finish($ctx, $out);
$hash3 = ParagonIE_Sodium_Core32_BLAKE2b::SplFixedArrayToString($out);
} else {
$d1s = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($data);
$d2s = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($data2);
$key = ParagonIE_Sodium_Core_BLAKE2b::stringToSplFixedArray($k);
$ctx = ParagonIE_Sodium_Core_BLAKE2b::init($key, 32);
ParagonIE_Sodium_Core_BLAKE2b::update($ctx, $d1s, $d1s->count());
ParagonIE_Sodium_Core_BLAKE2b::update($ctx, $d2s, $d2s->count());
ParagonIE_Sodium_Core_BLAKE2b::finish($ctx, $out);
$hash3 = ParagonIE_Sodium_Core_BLAKE2b::SplFixedArrayToString($out);
}
$this->assertSame(bin2hex($hash), bin2hex($hash3), 'Generichash streaming is failing (' . $i . ') a');
$this->assertSame(bin2hex($hash2), bin2hex($hash3), 'Generichash streaming is failing (' . $i . ') b');
$this->assertSame(bin2hex($hash2), bin2hex($hash), 'Generichash streaming is failing (' . $i . ') c');
}
/**
* @covers ParagonIE_Sodium_Core_BLAKE2b
* @throws SodiumException
* @throws TypeError
*/
public function testRotate()
{
if (PHP_INT_SIZE === 4) {
$int = ParagonIE_Sodium_Core32_BLAKE2b::new64(0x7f000000, 0x3ffffff0);
$expected = ParagonIE_Sodium_Core32_BLAKE2b::new64(0x3f800000, 0x1ffffff8);
$calc = ParagonIE_Sodium_Core32_BLAKE2b::rotr64($int, 1);
$this->assertEquals($expected->toArray(), $calc->toArray());
$expected = ParagonIE_Sodium_Core32_BLAKE2b::new64(0xfff07f00, 0x00003fff);
$calc = ParagonIE_Sodium_Core32_BLAKE2b::rotr64($int, 16);
$this->assertEquals($expected->toArray(), $calc->toArray());
$expected = ParagonIE_Sodium_Core32_BLAKE2b::new64(0x3ffffff0, 0x7f000000);
$calc = ParagonIE_Sodium_Core32_BLAKE2b::rotr64($int, 32);
$this->assertEquals($expected->toArray(), $calc->toArray());
} else {
$int = ParagonIE_Sodium_Core_BLAKE2b::new64(0x7f000000, 0x3ffffff0);
$expected = ParagonIE_Sodium_Core_BLAKE2b::new64(0x3f800000, 0x1ffffff8);
$calc = ParagonIE_Sodium_Core_BLAKE2b::rotr64($int, 1);
$this->assertEquals($expected->toArray(), $calc->toArray());
$expected = ParagonIE_Sodium_Core_BLAKE2b::new64(0xfff07f00, 0x00003fff);
$calc = ParagonIE_Sodium_Core_BLAKE2b::rotr64($int, 16);
$this->assertEquals($expected->toArray(), $calc->toArray());
$expected = ParagonIE_Sodium_Core_BLAKE2b::new64(0x3ffffff0, 0x7f000000);
$calc = ParagonIE_Sodium_Core_BLAKE2b::rotr64($int, 32);
$this->assertEquals($expected->toArray(), $calc->toArray());
}
}
}
|