From f96f3505a8aaae4d8921ead61696b6ad70ed64ab Mon Sep 17 00:00:00 2001 From: terrafrost Date: Tue, 8 Feb 2022 20:10:34 -0600 Subject: [PATCH] Hash: add support for keccak256 --- phpseclib/Crypt/Hash.php | 17 ++++++++++------- tests/Unit/Crypt/HashTest.php | 20 ++++++++++++++++++-- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/phpseclib/Crypt/Hash.php b/phpseclib/Crypt/Hash.php index feed7896..ab0f488e 100644 --- a/phpseclib/Crypt/Hash.php +++ b/phpseclib/Crypt/Hash.php @@ -52,7 +52,7 @@ class Hash * * @access private */ - //const PADDING_KECCAK = 1; + const PADDING_KECCAK = 1; /** * Padding Types @@ -338,6 +338,8 @@ class Hash case 'sha3-224': $this->length = 28; break; + case 'keccak256': + $this->paddingType = self::PADDING_KECCAK; case 'sha256': case 'sha512/256': case 'sha3-256': @@ -383,6 +385,7 @@ class Hash break; case 'sha3-256': case 'shake256': + case 'keccak256': $this->blockSize = 1088; // 1600 - 2*256 break; case 'sha3-384': @@ -398,10 +401,10 @@ class Hash $this->blockSize = 1024; } - if (in_array(substr($hash, 0, 5), ['sha3-', 'shake'])) { + if (in_array(substr($hash, 0, 5), ['sha3-', 'shake', 'kecca'])) { // PHP 7.1.0 introduced support for "SHA3 fixed mode algorithms": // http://php.net/ChangeLog-7.php#7.1.0 - if (version_compare(PHP_VERSION, '7.1.0') < 0 || substr($hash, 0,5) == 'shake') { + if (version_compare(PHP_VERSION, '7.1.0') < 0 || substr($hash, 0,5) != 'sha3-') { //preg_match('#(\d+)$#', $hash, $matches); //$this->parameters['capacity'] = 2 * $matches[1]; // 1600 - $this->blockSize //$this->parameters['rate'] = 1600 - $this->parameters['capacity']; // == $this->blockSize @@ -930,10 +933,10 @@ class Hash private static function sha3_pad($padLength, $padType) { switch ($padType) { - //case self::PADDING_KECCAK: - // $temp = chr(0x06) . str_repeat("\0", $padLength - 1); - // $temp[$padLength - 1] = $temp[$padLength - 1] | chr(0x80); - // return $temp + case self::PADDING_KECCAK: + $temp = chr(0x01) . str_repeat("\0", $padLength - 1); + $temp[$padLength - 1] = $temp[$padLength - 1] | chr(0x80); + return $temp; case self::PADDING_SHAKE: $temp = chr(0x1F) . str_repeat("\0", $padLength - 1); $temp[$padLength - 1] = $temp[$padLength - 1] | chr(0x80); diff --git a/tests/Unit/Crypt/HashTest.php b/tests/Unit/Crypt/HashTest.php index 80e57f40..84c1b924 100644 --- a/tests/Unit/Crypt/HashTest.php +++ b/tests/Unit/Crypt/HashTest.php @@ -144,7 +144,23 @@ class Unit_Crypt_HashTest extends PhpseclibTestCase 'shake256-912', // this is what Ed448 uses str_repeat('a', 135), // one character shy of the block size (136) '55b991ece1e567b6e7c2c714444dd201cd51f4f3832d08e1d26bebc63e07a3d7ddeed4a5aa6df7a15f89f2050566f75d9cf1a4dea4ed1f578df0985d5706d49e877d9a913dcdbc26a4c4e807ec72dc10438df95873e24660e39cd49aa4e5df286cb5ba60eaad91ff134754c21cd736681a8f' - ] + ], + // from https://docs.ethers.io/v5/api/utils/hashing/ + [ + 'keccak256', // used by Ethereum + "\x12\x34", + '56570de287d73cd1cb6092bb8fdee6173974955fdef345ae579ee9f475ea7432' + ], + [ + 'keccak256', + '', + 'c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470' + ], + [ + 'keccak256', + 'hello world', + '47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad' + ], ]; } @@ -362,7 +378,7 @@ class Unit_Crypt_HashTest extends PhpseclibTestCase */ public function testHash96($hash, $message, $result) { - if (preg_match('#^sha3-\d+#', $hash) || preg_match('#^shake(?:128|256)-\d+#', $hash)) { + if (preg_match('#^sha3-\d+#', $hash) || preg_match('#^shake(?:128|256)-\d+#', $hash) || $hash === 'keccak256') { self::markTestSkipped($hash . '-96 not supported'); } $this->assertHashesTo($hash . '-96', $message, substr($result, 0, 24));