Do You Know Your Keccak From Your SHA-3, And Your SHAKE From Your KMAC

NIST choose Keccak as the standard for SHA-3. But, it’s all a bit confusing, as there are two main versions of this: Keccak and SHA-3. Many…

Photo by Mauro Sbicego on Unsplash

Do You Know Your Keccak From Your SHA-3, And Your SHAKE From Your KMAC

NIST choose Keccak as the standard for SHA-3. But, it’s all a bit confusing, as there are two main versions of this: Keccak and SHA-3. Many systems, such as Ethereum have adopted Keccak, while others go for SHA-3.

Keccak or SHA-3?

In 2006, NIST initiated the SHA-3 project, and the winner was announced in 2012. Basically, the only difference between SHA-3 and Keccak, is that NIST changed the padding of the data, and where the two hashing methods have the same security level. But, many still question why NIST did this. Some Node.js code for this is:

sha3_512 = require('js-sha3').sha3_512;
sha3_384 = require('js-sha3').sha3_384;
sha3_256 = require('js-sha3').sha3_256;
sha3_224 = require('js-sha3').sha3_224;
keccak512 = require('js-sha3').keccak512;
keccak384 = require('js-sha3').keccak384;
keccak256 = require('js-sha3').keccak256;
keccak224 = require('js-sha3').keccak224;
console.log("SHA-3 224: ",sha3_224(msg));
console.log("SHA-3 256: ",sha3_256(msg));
console.log("SHA-3 384: ",sha3_384(msg));
console.log("SHA-3 512: ",sha3_512(msg));
console.log("\nKeccak224: ",keccak224(msg));
console.log("Keccak256: ",keccak256(msg));
console.log("Keccak384: ",keccak384(msg));
console.log("Keccak512: ",keccak512(msg));

For ‘Hello’, we have four different hash sizes (224-bit, 256-bit, 384-bit and 512-bit) [here]:

=== Hash values ===
SHA-3 224: 4cf679344af02c2b89e4a902f939f4608bcac0fbf81511da13d7d9b9
SHA-3 256: 8ca66ee6b2fe4bb928a8e3cd2f508de4119c0895f22e011117e22cf9b13de7ef
SHA-3 384: df7e26e3d067579481501057c43aea61035c8ffdf12d9ae427ef4038ad7c13266a11c0a3896adef37ad1bc85a2b5bdac
SHA-3 512: 0b8a44ac991e2b263e8623cfbeefc1cffe8c1c0de57b3e2bf1673b4f35e660e89abd18afb7ac93cf215eba36dd1af67698d6c9ca3fdaaf734ffc4bd5a8e34627
Keccak224:  2a2543591ab61b478869d18143de26f24e38e9e65e666da819683a55
Keccak256: 06b3dfaec148fb1bb2b066f10ec285e7c9bf402ab32aa78a5d38e34566810cd2
Keccak384: f0bb87a2892365fa78c9a9e3260221f489e43f0cc7a4182039d2bd17e20f98352a77ab31b0146c61d2dc2f0193c6d995
Keccak512: c33fede18a1ae53ddb8663710f8054866beb714044fce759790459996196f101d94dfc7bd8268577f7ee3d2f8ff0cef4004a9632227db84df62d2b40682d69e2

SHAKE it up

And so, these are fixed length output hashes, but in many applications, we need a variable length output, such as when we create random numbers or encryption keys. For this, we can use SHAKE, and where we define the length of the output in bytes: Luckily, we only have SHAKE128 and SHAKE256:

console.log("SHAKE 128: ",shake128(msg, size*8));
console.log("SHAKE 256: ",shake256(msg, size*8));

For ‘Hello’ with 32 bytes we get [here]:

SHAKE 128:  4131f8db5745776b48b86caa68d251fa9b19cf46b92b16289bb0c98e57e0e0de
SHAKE 256: 555796c90bfb8f3256a1cb0d7e574877fd48750e4147cf40aa43da122b4d64da

and 16 bytes:

SHAKE 128:  4131f8db5745776b48b86caa68d251fa
SHAKE 256: 555796c90bfb8f3256a1cb0d7e574877

cSHAKE

Now, we can add a separation string with cSHAKE, and which adds a salt value. This can be used by different applications, to produce different hashes within their applications — or could be used as a salt value:

console.log("\ncSHAKE 128: ",cshake128(msg, size*8, N,S));
console.log("cSHAKE 256: ",cshake256(msg, size*8, N, S));

For a message of “Hello” and a separation string of “Email Signature”, we generate [here]:

cSHAKE 128:  38ba95b8218ec05c303c2d2c4b3ec805
cSHAKE 256: d394da24873723ccb17b7c8acf8d586e
Message: Hello
Customizaton string (S): Email Signature
N:
Size: 16 Bytes
cSHAKE 128:  38ba95b8218ec05c303c2d2c4b3ec805
cSHAKE 256: d394da24873723ccb17b7c8acf8d586e

Another parameter is N, but this is typically only used for NIST registered strings.

KMAC

Now, we need a way to replace HMAC, with Keccak. With this we create KMAC, and which requires an encryption key. With this Bob and Alice can share the same secret key, and then they can sign a message with their secret key, and the other one can validate the signature. In the following, we have a key (mykey), a message (msg), and a tag size:

console.log("KMAC128: ",kmac128(mykey, msg, size*8, ''));
console.log("KMAC256: ",kmac256(mykey, msg, size*8, ''));

A sample run gives:

Message:  Hello
Customizaton string (S): Email Signature
N:
Size: 16 Bytes
Key (K): key1234
KMAC128:  06545dd2988afac2642714cac85faa6e
KMAC256: 749a073a39cb16c686442a245d449eeb

And here is the complete code:

https://asecuritysite.com/hash/cs2