A cryptographic hash (sometimes called ‘digest’) is a kind of ‘signature’ for a text or a data file. The SHA-3 (Keccak) family of hash routines generate almost-unique 224-bit, 256-bit, 384-bit, or 512-bit (28-/32-/48-/64-byte) signatures for a text. See below for the source code.
Since JavaScript has no native 64-bit integers (SHA-3 specifies the Keccak lane length ‘b’ as 64), I have used the arbitrary-precision BigInt
. This means it will be less performant than implementations in languages which can use native 64-bit integer types. Nonetheless, JavaScript is a good candidate for a ‘reference implementation’ to aid understanding of the algorithms; it is widely used and understood, its untyped C-style syntax is easily followed, and it has acquired convenient functional-style elements.
Even the SHA-3 ‘reference’ implementations I found left me scratching my head a bit, so I thought that to complement my existing implementations of SHA1 and SHA-2 (SHA256 & SHA512), I would make this SHA-3 implementation. SHA-3 / Keccak lends itself to a wide variety of implementations / optimisations – I have deviated as little as possible from the reference; I am anything but a cryptography expert, and have no inclination to ‘improve’ on the algorithms documented in the original references/standard, just to help understanding them. Note that while there are no ‘magic numbers’ in Keccak, it is conventional to pre-calculate the round constants for the ι (iota) step. It is also conventional to combine the ρ and π steps, as explained in the code. §ection numbers relate the code back to sections in the Keccak reference.
Using Chrome on a low-to-middling Core i5 PC, in timing tests this script will hash a short message in around 0.4 – 0.6 ms; longer messages will be hashed at a speed of around 0.2 – 0.4 MB/sec.
Note that these scripts are intended to assist in studying the algorithms, not for production use. For production use, I would recommend the Web Cryptography API for the browser (see example), or the crypto library in Node.js. For password hashing, I have a WebCrypto example using PBKDF2.
Source code (below) is also available on GitHub. §ection numbers relate the code back to sections in the Keccak reference.
With its untyped C-style syntax, JavaScript reads remarkably close to pseudo-code: exposing the algorithms with a minimum of syntactic distractions. This code is to aid understanding of the algorithms, though can also be used as-is in browsers and Node.js, where performance is not a prime consideration.
I offer these scripts for free use and adaptation to balance my debt to the open-source info-verse. You are welcome to re-use these scripts [under an MIT licence, without any warranty express or implied] provided solely that you retain my copyright notice and a link to this page.
If you have any queries or find any problems, contact me at ku.oc.epyt-elbavom@cne-stpircs.
© 2016–2020 Chris Veness