WebAssembly port of SHA-1, SHA-256, Keccak-256, RIPEMD-160, and CRC-32 hashing algorithms
npm i @hazae41/morax
Node Package π¦ β’ Deno Module π¦ β’ Next.js CodeSandbox πͺ£
- Incremental SHA-1 from RustCrypto (sha1)
- Incremental SHA-256 from RustCrypto (sha2)
- Incremental Keccak-256 from RustCrypto (sha3)
- Incremental RIPEMD-160 from RustCrypto (ripemd)
- Incremental CRC-32 from Sam Rijs (crc32fast)
- Reproducible building
- Pre-bundled and streamed
- Zero-copy memory slices
cpu: Apple M1 Max
runtime: deno 1.30.3 (arm64-darwin)
ββββββββββββββββββββββββββ¬ββββββββββββββββββ¬βββββββββββββ¬ββββββββββββββ
β (idx) β average β minimum β maximum β
ββββββββββββββββββββββββββΌββββββββββββββββββΌβββββββββββββΌββββββββββββββ€
β wasm sha1 β "9.41 ΞΌs/iter" β "6.88 ΞΌs" β "199.92 ΞΌs" β
β webcrypto sha1 β "24.46 ΞΌs/iter" β "14.92 ΞΌs" β "360.38 ΞΌs" β
β node:crypto sha1 β "20.75 ΞΌs/iter" β "13.08 ΞΌs" β "3.56 ms" β
β npm:@noble/hashes/sha1 β "19.92 ΞΌs/iter" β "15.87 ΞΌs" β "759.75 ΞΌs" β
ββββββββββββββββββββββββββ΄ββββββββββββββββββ΄βββββββββββββ΄ββββββββββββββ
Summary
- wasm sha1 is 2.60x faster than WebCrypto
- wasm sha1 is 2.21x faster than node:crypto
- wasm sha1 is 2.12x faster than npm:@noble/hashes
cpu: Apple M1 Max
runtime: node v18.12.1 (arm64-darwin)
ββββββββββββββββββββββββββ¬ββββββββββββββββββ¬ββββββββββββ¬ββββββββββββββ
β (index) β average β minimum β maximum β
ββββββββββββββββββββββββββΌββββββββββββββββββΌββββββββββββΌββββββββββββββ€
β wasm sha1 β '6.07 ΞΌs/iter' β '5.37 ΞΌs' β '23.71 ΞΌs' β
β webcrypto sha1 β '12.34 ΞΌs/iter' β '9.04 ΞΌs' β '852.58 ΞΌs' β
β node:crypto sha1 β '3.48 ΞΌs/iter' β '2.83 ΞΌs' β '88.50 ΞΌs' β
β npm:@noble/hashes/sha1 β '7.34 ΞΌs/iter' β '6.37 ΞΌs' β '746.42 ΞΌs' β
ββββββββββββββββββββββββββ΄ββββββββββββββββββ΄ββββββββββββ΄ββββββββββββββ
Summary
- wasm sha1 is 2.03x faster than WebCrypto
- wasm sha1 is 0.57x faster than node:crypto
- wasm sha1 is 1.21x faster than npm:@noble/hashes
βββββββββββββββββββββ¬ββββββββββββββββββ¬βββββββββββββ¬ββββββββββββββ
β (idx) β average β minimum β maximum β
βββββββββββββββββββββΌββββββββββββββββββΌβββββββββββββΌββββββββββββββ€
β wasm keccak256 β "4.91 ΞΌs/iter" β "4.37 ΞΌs" β "25.37 ΞΌs" β
β npm:@noble/hashes β "60.01 ΞΌs/iter" β "57.83 ΞΌs" β "195.50 ΞΌs" β
βββββββββββββββββββββ΄ββββββββββββββββββ΄βββββββββββββ΄ββββββββββββββ
Summary
- wasm keccak256 is 12.22x faster than npm:@noble/hashes
cpu: Apple M1 Max
runtime: node v20.3.1 (arm64-darwin)
βββββββββββββββββββββ¬ββββββββββββββββββ¬βββββββββββββ¬ββββββββββββββ
β (index) β average β minimum β maximum β
βββββββββββββββββββββΌββββββββββββββββββΌβββββββββββββΌββββββββββββββ€
β wasm keccak256 β '3.10 ΞΌs/iter' β '2.92 ΞΌs' β '104.00 ΞΌs' β
β npm:@noble/hashes β '62.28 ΞΌs/iter' β '60.21 ΞΌs' β '166.33 ΞΌs' β
βββββββββββββββββββββ΄ββββββββββββββββββ΄βββββββββββββ΄ββββββββββββββ
Summary
- wasm keccak256 is 20.08x faster than npm:@noble/hashes
cpu: Apple M1 Max
runtime: deno 1.30.3 (arm64-darwin)
ββββββββββββββ¬βββββββββββββββββ¬ββββββββββββ¬ββββββββββββββ
β (idx) β average β minimum β maximum β
ββββββββββββββΌβββββββββββββββββΌββββββββββββΌββββββββββββββ€
β wasm crc32 β "3.04 ΞΌs/iter" β "2.17 ΞΌs" β "198.04 ΞΌs" β
β npm:crc-32 β "4.36 ΞΌs/iter" β "2.04 ΞΌs" β "97.96 ΞΌs" β
ββββββββββββββ΄βββββββββββββββββ΄ββββββββββββ΄ββββββββββββββ
Summary
- wasm crc32 is 1.44x faster than npm:crc-32
cpu: Apple M1 Max
runtime: node v18.12.1 (arm64-darwin)
ββββββββββββββ¬βββββββββββββββββ¬ββββββββββββ¬βββββββββββββ
β (index) β average β minimum β maximum β
ββββββββββββββΌβββββββββββββββββΌββββββββββββΌβββββββββββββ€
β wasm crc32 β '2.40 ΞΌs/iter' β '2.00 ΞΌs' β '53.88 ΞΌs' β
β npm:crc-32 β '3.73 ΞΌs/iter' β '2.25 ΞΌs' β '1.11 ms' β
ββββββββββββββ΄βββββββββββββββββ΄ββββββββββββ΄βββββββββββββ
Summary
- wasm crc32 is 1.55x faster than npm:crc-32
import { Morax, sha1 } from "@hazae41/morax";
// Wait for WASM to load
await Morax.initBundledOnce()
// Data to be hashed
const hello = new TextEncoder().encode("Hello World")
// Grab the digest (Uint8Array)
const digest = sha1(hello).copyAndDispose()
import { Morax, crc32 } from "@hazae41/morax";
// Wait for WASM to load
await Morax.initBundledOnce()
// Data to be hashed
const hello = new TextEncoder().encode("Hello World")
// Grab the digest (number)
const digest = crc32(hello)
import { Morax, Sha1Hasher } from "@hazae41/morax";
// Wait for WASM to load
await Morax.initBundledOnce()
// Create a hash
const hasher = new Sha1Hasher()
// Data to be hashed
const hello = new TextEncoder().encode("Hello World")
// Update the hash with your data
hasher.update(hello)
// Grab the digest (Uint8Array)
const digest = hasher.finalize().copyAndDispose()
// Update the hash another time
hasher.update(hello)
// Grab the digest (Uint8Array)
const digest2 = hasher.finalize().copyAndDispose()
// digest !== digest2
console.log(digest)
console.log(digest2)
hasher.free()
import { Morax, Crc32Hasher } from "@hazae41/morax";
// Wait for WASM to load
await Morax.initBundledOnce()
// Create a hash
const hasher = new Crc32Hasher()
// Data to be hashed
const hello = new TextEncoder().encode("Hello World")
// Update the hash with your data
hasher.update(hello)
// Grab the checksum (number)
const checksum = hasher.finalize()
// Update the hash another time
hasher.update(hello)
// Grab the checksum (number)
const checksum2 = hasher.finalize()
// checksum !== checksum2
console.log(checksum)
console.log(checksum2)
hasher.free()
You need to install Rust
Then, install wasm-pack
cargo install wasm-pack
Finally, do a clean install and build
npm ci && npm run build
You can build the exact same bytecode using Docker, just be sure you're on a linux/amd64
host
docker compose up --build
Then check that all the files are the same using git status
git status --porcelain
If the output is empty then the bytecode is the same as the one I commited
Each time I commit to the repository, the GitHub's CI does the following:
- Clone the repository
- Reproduce the build using
docker compose up --build
- Throw an error if the
git status --porcelain
output is not empty
Each time I release a new version tag on GitHub, the GitHub's CI does the following:
- Clone the repository
- Do not reproduce the build, as it's already checked by the task above
- Throw an error if there is a
npm diff
between the cloned repository and the same version tag on NPM
If a version is present on NPM but not on GitHub, do not use!