PHP Classes

File: tests/unit/Int64Test.php

Recommend this page to a friend!
  Classes of Scott Arciszewski   PHP Sodium Compat   tests/unit/Int64Test.php   Download  
File: tests/unit/Int64Test.php
Role: Class source
Content type: text/plain
Description: Class source
Class: PHP Sodium Compat
Cryptographic functions of libsodium in pure PHP
Author: By
Last change: Fix more int-float error messages
Date: 1 year ago
Size: 18,581 bytes
 

Contents

Class file image Download
<?php /** * Class Int64Test */ class Int64Test extends PHPUnit_Framework_TestCase { /** * @before */ public function before() { if (PHP_INT_SIZE === 8) { $this->markTestSkipped('Only relevant to 32-bit platforms.'); } } /** * @throws SodiumException * @throws TypeError */ public function testAssociative() { if (PHP_INT_SIZE === 8) { $this->markTestSkipped('Only relevant to 32-bit platforms.'); return; } // Test negative operands $f = new ParagonIE_Sodium_Core32_Int64(array(0, 0, 409, 49299)); $g = new ParagonIE_Sodium_Core32_Int64(array(65535, 65535, 65369, 30902)); $this->assertSame( array(65534, 62836, 38318, 53378), $g->mulInt64($f)->limbs, 'G x F first run -- step one' ); $this->assertSame( array(65534, 62836, 38318, 53378), $f->mulInt64($g)->limbs, 'F x G first run -- step two' ); for ($i = 64; $i >= 32; --$i) { $this->assertSame( array(65534, 62836, 38318, 53378), $g->mulInt64($f, $i)->limbs, 'LOOP: G x F -- Failed at $i = ' . $i ); } for ($i = 64; $i >= 32; --$i) { $this->assertSame( array(65534, 62836, 38318, 53378), $f->mulInt64($g, $i)->limbs, 'LOOP: F x G -- Failed at $i = ' . $i ); } } /** * @throws SodiumException * @throws TypeError */ public function testConversion() { if (PHP_INT_SIZE === 8) { $this->markTestSkipped('Only relevant to 32-bit platforms.'); return; } $binary = ParagonIE_Sodium_Compat::hex2bin("0123456789abcdef"); $from = ParagonIE_Sodium_Core32_Int64::fromString($binary); $this->assertSame( array(0x0123, 0x4567, 0x89ab, 0xcdef), $from->limbs, 'fromString()' ); $this->assertSame( bin2hex($binary), bin2hex((string) $from) ); } /** * @covers ParagonIE_Sodium_Core32_Int64::addInt64() * @throws SodiumException * @throws TypeError */ public function testAddInt64() { if (PHP_INT_SIZE === 8) { $this->markTestSkipped('Only relevant to 32-bit platforms.'); return; } $one = new ParagonIE_Sodium_Core32_Int64( array(0x0000, 0x0000, 0x0000, 0x0001) ); $this->assertSame( array(0x0000, 0x0000, 0x0000, 0x0004), $one->addInt64( new ParagonIE_Sodium_Core32_Int64( array(0x0000, 0x0000, 0x0000, 0x0003) ) )->limbs, 'Adding 1 to 3 should yield 4' ); $this->assertSame( array(0x0000, 0x0001, 0x0000, 0x0000), $one->addInt64( new ParagonIE_Sodium_Core32_Int64( array(0x0000, 0x0000, 0xffff, 0xffff) ) )->limbs, 'Adding 1 to 0xfffffffff should yield 0x1000000000' ); $this->assertSame( array(0x0000, 0x0000, 0x0000, 0x0000), $one->addInt64( new ParagonIE_Sodium_Core32_Int64( array(0xffff, 0xffff, 0xffff, 0xffff) ) )->limbs, 'Adding 1 to 0xfffffffffffffffff should yield 0, when conforming to uint64' ); $tests = array( array('1660a70000000000', '0000c002ec140000', 21) ); foreach ($tests as $sample => $test) { list ($A, $B, $C) = $test; $a = ParagonIE_Sodium_Core32_Int64::fromReverseString(ParagonIE_Sodium_Core_Util::hex2bin($A)); $b = ParagonIE_Sodium_Core32_Int64::fromReverseString(ParagonIE_Sodium_Core_Util::hex2bin($B)); $this->assertEquals( $b->limbs, $a->shiftLeft($C)->limbs, 'Sample ' .$sample ); } } /** * @covers ParagonIE_Sodium_Core32_Int64::addInt64() * @throws SodiumException * @throws TypeError */ public function testAddInt() { if (PHP_INT_SIZE === 8) { $this->markTestSkipped('Only relevant to 32-bit platforms.'); return; } $one = new ParagonIE_Sodium_Core32_Int64( array(0x0000, 0x0000, 0x0000, 0x0001) ); $this->assertSame( array(0x0000, 0x0000, 0x0000, 0x0004), $one->addInt(3)->limbs, 'Adding 1 to 3 should yield 4' ); $big = new ParagonIE_Sodium_Core32_Int64( array(0x0000, 0x0000, 0xffff, 0xffff) ); $this->assertSame( array(0x0000, 0x0001, 0x0000, 0x0002), $big->addInt(3)->limbs ); $vbig = new ParagonIE_Sodium_Core32_Int64( array(0xffff, 0xffff, 0xffff, 0xffff) ); $this->assertSame( array(0x0000, 0x0000, 0x0000, 0x0000), $vbig->addInt(1)->limbs ); $this->assertSame( array(0x0000, 0x0000, 0x0000, 0x0001), $vbig->addInt(2)->limbs ); } /** * @covers ParagonIE_Sodium_Core32_Int64::mulInt() * @covers ParagonIE_Sodium_Core32_Int64::mulInt64() * @throws SodiumException * @throws TypeError * @throws Exception */ public function testMult() { if (PHP_INT_SIZE === 8) { $this->markTestSkipped('Only relevant to 32-bit platforms.'); return; } $begin = new ParagonIE_Sodium_Core32_Int64( array(0x1234, 0x5678, 0x9abc, 0xdef0) ); $this->assertSame( array(0x2468, 0xacf1, 0x3579, 0xbde0), $begin->mulInt(2)->limbs ); $this->assertSame( array(0x48d1, 0x59e2, 0x6af3, 0x7bc0), $begin->mulInt(4)->limbs ); $this->assertSame( array(0x5b05, 0xb05b, 0x05b0, 0x5ab0), $begin->mulInt(5)->limbs ); $this->assertSame( array(0, 0, 0, 0), $begin->mulInt(0)->limbs ); $this->assertSame( array(0x48d1, 0x59e2, 0x6af3, 0x7bc0), $begin->mulInt64(new ParagonIE_Sodium_Core32_Int64(array(0, 0, 0, 4)))->limbs ); $negOne = new ParagonIE_Sodium_Core32_Int64(array(0xffff, 0xffff, 0xffff, -1 & 0xffff)); $this->assertSame( array(0xffff, 0xffff, 0xffff, 0xfffb), $negOne->mulInt(5)->limbs ); $this->assertSame( array(0, 0, 0, 5), $negOne->mulInt(-5)->limbs ); $one = new ParagonIE_Sodium_Core32_Int64(array(0, 0, 0, 1)); $this->assertSame( array(0, 0, 0, 5), $one->mulInt(5)->limbs ); $two = new ParagonIE_Sodium_Core32_Int64(array(0, 0, 0, 2)); $this->assertSame( array(0, 0, 0, 10), $two->mulInt(5)->limbs ); for ($j = 0; $j < 64; ++$j) { $baseSmall = random_int(1, 65536); $base = new ParagonIE_Sodium_Core32_Int64(array(0, 0, 0, $baseSmall)); for ($i = 0; $i < 64; ++$i) { $value = random_int(1, 65536); $result = ($baseSmall * $value); $expected = array( 0, 0, ((int) $result >> 16) & 0xffff, (int) $result & 0xffff ); $this->assertSame( $expected, $base->mulInt($value)->limbs, $baseSmall . ' x ' . $value . ' = ' . $result ); } } $negTwo = new ParagonIE_Sodium_Core32_Int64(array(0xffff, 0xffff, 0xffff, -2 & 0xffff)); $this->assertSame( array(0, 0, 0, 0), $negTwo->mulInt64(new ParagonIE_Sodium_Core32_Int64())->limbs ); $this->assertSame( array(0, 0, 0, 2), $negTwo->mulInt64($negOne)->limbs ); $this->assertSame( $negTwo->limbs, $negTwo->mulInt64($one)->limbs ); $three = new ParagonIE_Sodium_Core32_Int64(array(0, 0, 0, 3)); $this->assertSame( array(0xffff, 0xffff, 0xffff, -6 & 0xffff), $negTwo->mulInt64($three)->limbs ); $negThree = new ParagonIE_Sodium_Core32_Int64(array(0xffff, 0xffff, 0xffff, -3 & 0xffff)); $this->assertSame( array(0, 0, 0, 6), $negTwo->mulInt64($negThree)->limbs ); $f1 = ParagonIE_Sodium_Core32_Int64::fromReverseString(ParagonIE_Sodium_Core_Util::hex2bin('0000000000000000')); $g0 = ParagonIE_Sodium_Core32_Int64::fromReverseString(ParagonIE_Sodium_Core_Util::hex2bin('6a5882feffffffff')); $this->assertSame( array(0, 0, 0, 0), $g0->mulInt64($f1)->limbs ); $this->assertSame( array(0, 0, 0, 0), $f1->mulInt64($g0)->limbs ); } /** * @covers ParagonIE_Sodium_Core32_Int64::mulInt() * @covers ParagonIE_Sodium_Core32_Int64::mulInt64() * @throws SodiumException * @throws TypeError */ public function testMultNegative() { if (PHP_INT_SIZE === 8) { $this->markTestSkipped('Only relevant to 32-bit platforms.'); return; } $a = new ParagonIE_Sodium_Core32_Int64( array(0, 0, 0, 3) ); $na = new ParagonIE_Sodium_Core32_Int64( array(0xffff, 0xffff, 0xffff, 0xfffd) // -3 ); $b = new ParagonIE_Sodium_Core32_Int64( array(0, 0, 0, 14) ); $nb = new ParagonIE_Sodium_Core32_Int64( array(0xffff, 0xffff, 0xffff, 0xfff2) // -14 ); $this->assertEquals( $a->mulInt64($b)->limbs, $na->mulInt64($nb)->limbs ); $this->assertEquals( $a->mulInt64($nb)->limbs, $na->mulInt64($b)->limbs ); $this->assertEquals( 42, $a->mulInt64($b)->toInt32()->toInt() ); $this->assertEquals( 42, $na->mulInt64($nb)->toInt32()->toInt() ); $this->assertEquals( dechex(-42), dechex($na->mulInt64($b)->toInt32()->toInt()) ); $this->assertEquals( -42, $a->mulInt64($nb)->toInt32()->toInt() ); } /** * @covers ParagonIE_Sodium_Core32_Int64::rotateLeft() * @throws SodiumException * @throws TypeError */ public function testRotateLeft() { if (PHP_INT_SIZE === 8) { $this->markTestSkipped('Only relevant to 32-bit platforms.'); return; } $int64 = new ParagonIE_Sodium_Core32_Int64( array(0x0123, 0x4567, 0x89ab, 0xcdef) ); $this->assertSame( $int64->limbs, $int64->rotateLeft(0)->limbs, 'NOP' ); $this->assertSame( array(0x4567, 0x89ab, 0xcdef, 0x0123), $int64->rotateLeft(16)->limbs, 'Rotate left by 16' ); $this->assertSame( array(0x89ab, 0xcdef, 0x0123, 0x4567), $int64->rotateLeft(32)->limbs, 'Rotate left by 32' ); $this->assertSame( array(0x1234, 0x5678, 0x9abc, 0xdef0), $int64->rotateLeft(4)->limbs, 'Rotate left by 4' ); $this->assertSame( array(0x0246, 0x8acf, 0x1357, 0x9bde), $int64->rotateLeft(1)->limbs, 'Rotate left by 1' ); $second = new ParagonIE_Sodium_Core32_Int64( array(0x0001, 0x0000, 0x0000, 0x0000) ); $this->assertSame( array(0x0000, 0x0000, 0x0000, 0x0001), $second->rotateLeft(16)->limbs, 'Rotate left by 16' ); $this->assertSame( array(0x0000, 0x0000, 0x0000, 0x8000), $second->rotateLeft(31)->limbs, 'Rotate left by 31' ); $this->assertSame( array(0x0000, 0x0000, 0x0001, 0x0000), $second->rotateLeft(32)->limbs, 'Rotate left by 32' ); } /** * @covers ParagonIE_Sodium_Core32_Int64::rotateRight() * @throws SodiumException * @throws TypeError */ public function testRotateRight() { if (PHP_INT_SIZE === 8) { $this->markTestSkipped('Only relevant to 32-bit platforms.'); return; } $int64 = new ParagonIE_Sodium_Core32_Int64( array(0x0123, 0x4567, 0x89ab, 0xcdef) ); $this->assertSame( $int64->limbs, $int64->rotateRight(0)->limbs, 'NOP' ); $this->assertSame( array(0xcdef, 0x0123, 0x4567, 0x89ab), $int64->rotateRight(16)->limbs, 'Rotate right by 16' ); $this->assertSame( array(0x89ab, 0xcdef, 0x0123, 0x4567), $int64->rotateRight(32)->limbs, 'Rotate right by 32' ); $this->assertSame( array(0xf012, 0x3456, 0x789a, 0xbcde), $int64->rotateRight(4)->limbs, 'Rotate right by 4' ); $this->assertSame( array(0x8091, 0xa2b3, 0xc4d5, 0xe6f7), $int64->rotateRight(1)->limbs, 'Rotate right by 1' ); $second = new ParagonIE_Sodium_Core32_Int64( array(0x0001, 0x0000, 0x0000, 0x0000) ); $this->assertSame( array(0x0000, 0x0001, 0x0000, 0x0000), $second->rotateRight(16)->limbs, 'Rotate right by 16' ); $this->assertSame( array(0x0000, 0x0000, 0x0002, 0x0000), $second->rotateRight(31)->limbs, 'Rotate right by 31' ); $this->assertSame( array(0x0000, 0x8000, 0x0000, 0x0000), $second->rotateRight(1)->limbs, 'Rotate right by 1' ); $this->assertSame( array(0x0000, 0x0000, 0x0001, 0x0000), $second->rotateRight(32)->limbs, 'Rotate right by 32' ); } /** * @throws SodiumException * @throws TypeError */ public function testShift() { if (PHP_INT_SIZE === 8) { $this->markTestSkipped('Only relevant to 32-bit platforms.'); return; } $int64 = new ParagonIE_Sodium_Core32_Int64( array(0x0123, 0x4567, 0x89ab, 0xcdef) ); $this->assertSame( array(0x0246, 0x8acf, 0x1357, 0x9bde), $int64->shiftLeft(1)->limbs ); $this->assertSame( array(0x0000, 0x0123, 0x4567, 0x89ab), $int64->shiftRight(16)->limbs ); $second = new ParagonIE_Sodium_Core32_Int64( array(0x0001, 0x0000, 0x0000, 0x0000) ); $this->assertSame( array(0x1000, 0x0000, 0x0000, 0x0000), $second->shiftLeft(12)->limbs ); $this->assertSame( array(0x0000, 0x0000, 0x0001, 0x0000), $second->shiftRight(32)->limbs ); $real = new ParagonIE_Sodium_Core32_Int64( array(0, 3, 26984, 29696) ); $this->assertSame( array(0, 0, 0, 218), $real->shiftRight(26)->limbs ); $neg = new ParagonIE_Sodium_Core32_Int64( array(0xfedc, 0xba98, 0x7654, 0x3210) ); $this->assertSame( array(0xfffe, 0xdcba, 0x9876, 0x5432), $neg->shiftRight(8)->limbs ); $this->assertSame( array(0xffff, 0xfedc, 0xba98, 0x7654), $neg->shiftRight(16)->limbs ); $this->assertSame( array(0xffff, 0xfffe, 0xdcba, 0x9876), $neg->shiftRight(24)->limbs ); $this->assertSame( array(0xffff, 0xffff, 0xfedc, 0xba98), $neg->shiftRight(32)->limbs ); $neg = new ParagonIE_Sodium_Core32_Int64( array(0xffff, 0xfedc, 0xba98, 0x7654) ); $this->assertSame( array(0xffff, 0xfffe, 0xdcba, 0x9876), $neg->shiftRight(8)->limbs ); } /** * @throws SodiumException */ public function testSubInt64() { if (PHP_INT_SIZE === 8) { $this->markTestSkipped('Only relevant to 32-bit platforms.'); return; } $tests = array( array('07daac0d00000000', 'b1a1a51f00000000', 'aac7f81100000000'), array('98be457800000000', '70f3e84900000000', 'd834a3d1ffffffff'), array('c368b597ab6ee13c', 'ffd325e6adf3d40f', '3c6b704e0285f3d2'), array('c85d2b21ba98ff00', '938a6e5a72b9c400', 'cb2c4339b820c5ff'), array('0000c002ec140000', '3669be02ec140000', '3669feffffffffff'), array('0000c002e0140000', '3669be02ec140000', '3669feff0b000000') ); foreach ($tests as $sample => $test) { list ($A, $B, $C) = $test; $a = ParagonIE_Sodium_Core32_Int64::fromReverseString(ParagonIE_Sodium_Core_Util::hex2bin($A)); $b = ParagonIE_Sodium_Core32_Int64::fromReverseString(ParagonIE_Sodium_Core_Util::hex2bin($B)); $c = ParagonIE_Sodium_Core32_Int64::fromReverseString(ParagonIE_Sodium_Core_Util::hex2bin($C)); $this->assertEquals( $c->limbs, $b->subInt64($a)->limbs, 'Sample ' .$sample ); } } /** * @throws SodiumException * @throws TypeError */ public function testConvert() { if (PHP_INT_SIZE === 8) { $this->markTestSkipped('Only relevant to 32-bit platforms.'); return; } $int64 = new ParagonIE_Sodium_Core32_Int32(array(0xffff, 0xffff), true); $added = $int64->addInt(2)->toInt64(); $this->assertSame(array(0, 1, 0, 1), $added->limbs); $reverse = $added->toInt32(); $this->assertSame(array(0, 1), $reverse->limbs); $this->assertSame(1, $reverse->overflow); } }