<?php
declare(strict_types=1);
namespace ParagonIE\Discretion\Tests;
use ParagonIE\ConstantTime\Base64UrlSafe;
use ParagonIE\Discretion\Data\HiddenString;
use ParagonIE\Discretion\SimpleCrypto;
use PHPUnit\Framework\TestCase;
class SimpleCryptoTest extends TestCase
{
/**
* @covers SimpleCrypto::decryptRaw()
* @covers SimpleCrypto::encryptRaw()
*/
public function testEncryptDecryptRaw()
{
$key = new HiddenString(\random_bytes(32));
$message = new HiddenString('Test message goes here.');
$encrypted = SimpleCrypto::encryptRaw($message, $key);
$decrypted = SimpleCrypto::decryptRaw($encrypted, $key);
$this->assertSame($decrypted->getString(), $message->getString());
$forged = '' . $encrypted;
$forged[0] = \chr(\ord($forged[0]) ^ 0xff);
try {
SimpleCrypto::decrypt($forged, $key);
$this->fail('This should be failing.');
} catch (\Throwable $ex) {
$this->assertTrue(true);
}
// Test all bitflips.
for ($i = 0; $i < \mb_strlen($encrypted, '8bit'); ++$i) {
for ($j = 0; $j < 8; ++$j) {
$forged = '' . $encrypted;
$forged[$i] = \chr(\ord($forged[0]) ^ 1 << $j);
try {
SimpleCrypto::decrypt($forged, $key);
$this->fail('This should be failing.');
} catch (\Throwable $ex) {
$this->assertTrue(true);
}
}
}
}
/**
* @covers SimpleCrypto::decrypt()
* @covers SimpleCrypto::encrypt()
*/
public function testEncryptDecrypt()
{
$key = new HiddenString(\random_bytes(32));
$message = new HiddenString('Test message goes here.');
$encrypted = SimpleCrypto::encrypt($message, $key);
$decrypted = SimpleCrypto::decrypt($encrypted, $key);
$this->assertSame($decrypted->getString(), $message->getString());
$tmp = Base64UrlSafe::decode($encrypted);
$tmp[0] = \chr(\ord($tmp[0]) ^ 0xff);
$forged = Base64UrlSafe::encode($tmp);
try {
SimpleCrypto::decrypt($forged, $key);
$this->fail('This should be failing.');
} catch (\Throwable $ex) {
}
// Test all bitflips.
for ($i = 0; $i < \mb_strlen($encrypted, '8bit'); ++$i) {
for ($j = 0; $j < 8; ++$j) {
$tmp = Base64UrlSafe::decode($encrypted);
$tmp[0] = \chr(\ord($tmp[0]) ^ 1 << $j);
$forged = Base64UrlSafe::encode($tmp);
try {
SimpleCrypto::decrypt($forged, $key);
$this->fail('This should be failing.');
} catch (\Throwable $ex) {
$this->assertTrue(true);
}
}
}
}
}
|