{"id":14984991,"url":"https://github.com/hazae41/morax","last_synced_at":"2025-04-10T23:14:53.484Z","repository":{"id":61885600,"uuid":"555361363","full_name":"hazae41/morax","owner":"hazae41","description":"WebAssembly port of SHA-1, SHA-256, Keccak-256, RIPEMD-160, and CRC-32 hashing algorithms","archived":false,"fork":false,"pushed_at":"2023-11-20T10:21:27.000Z","size":803,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-10T23:14:43.352Z","etag":null,"topics":["browser","deno","hash","incremental","javascript","rust","sha1","typescript","wasm","web","webassembly","webcrypto"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hazae41.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-10-21T12:34:09.000Z","updated_at":"2023-09-12T15:50:15.000Z","dependencies_parsed_at":"2023-11-20T11:41:56.925Z","dependency_job_id":null,"html_url":"https://github.com/hazae41/morax","commit_stats":{"total_commits":60,"total_committers":3,"mean_commits":20.0,"dds":"0.033333333333333326","last_synced_commit":"6fa9eb5274461526e5c6ba966e820a408848a0e7"},"previous_names":[],"tags_count":30,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hazae41%2Fmorax","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hazae41%2Fmorax/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hazae41%2Fmorax/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hazae41%2Fmorax/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hazae41","download_url":"https://codeload.github.com/hazae41/morax/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248312134,"owners_count":21082638,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["browser","deno","hash","incremental","javascript","rust","sha1","typescript","wasm","web","webassembly","webcrypto"],"created_at":"2024-09-24T14:10:03.491Z","updated_at":"2025-04-10T23:14:53.469Z","avatar_url":"https://github.com/hazae41.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv\u003e\n  \u003cimg align=\"right\" width=\"128\" src=\"https://user-images.githubusercontent.com/4405263/216618885-198b5507-6e8b-4a38-aef0-dbca5957c744.png\"/\u003e\n  \u003cp\u003e\u003c/p\u003e\n\u003c/div\u003e\n\n# Morax\n\nWebAssembly port of SHA-1, SHA-256, Keccak-256, RIPEMD-160, and CRC-32 hashing algorithms\n\n```bash\nnpm i @hazae41/morax\n```\n\n[**Node Package 📦**](https://www.npmjs.com/package/@hazae41/morax) • [**Deno Module 🦖**](https://deno.land/x/morax) • [**Next.js CodeSandbox 🪣**](https://codesandbox.io/p/github/hazae41/morax-example-next)\n\n## Algorithms\n- Incremental SHA-1 from RustCrypto (sha1)\n- Incremental SHA-256 from RustCrypto (sha2)\n- Incremental Keccak-256 from RustCrypto (sha3)\n- Incremental RIPEMD-160 from RustCrypto (ripemd)\n- Incremental CRC-32 from Sam Rijs (crc32fast)\n\n## Features\n- Reproducible building\n- Pre-bundled and streamed\n- Zero-copy memory slices\n\n## Benchmarks\n\n### SHA-1\n\n#### Deno\n\n```\ncpu: Apple M1 Max\nruntime: deno 1.30.3 (arm64-darwin)\n\n┌────────────────────────┬─────────────────┬────────────┬─────────────┐\n│ (idx)                  │ average         │ minimum    │ maximum     │\n├────────────────────────┼─────────────────┼────────────┼─────────────┤\n│ wasm sha1              │ \"9.41 μs/iter\"  │ \"6.88 μs\"  │ \"199.92 μs\" │\n│ webcrypto sha1         │ \"24.46 μs/iter\" │ \"14.92 μs\" │ \"360.38 μs\" │\n│ node:crypto sha1       │ \"20.75 μs/iter\" │ \"13.08 μs\" │ \"3.56 ms\"   │\n│ npm:@noble/hashes/sha1 │ \"19.92 μs/iter\" │ \"15.87 μs\" │ \"759.75 μs\" │\n└────────────────────────┴─────────────────┴────────────┴─────────────┘\n\nSummary\n- wasm sha1 is 2.60x faster than WebCrypto\n- wasm sha1 is 2.21x faster than node:crypto\n- wasm sha1 is 2.12x faster than npm:@noble/hashes\n```\n\n#### Node\n\n```\ncpu: Apple M1 Max\nruntime: node v18.12.1 (arm64-darwin)\n\n┌────────────────────────┬─────────────────┬───────────┬─────────────┐\n│        (index)         │     average     │  minimum  │   maximum   │\n├────────────────────────┼─────────────────┼───────────┼─────────────┤\n│       wasm sha1        │ '6.07 μs/iter'  │ '5.37 μs' │ '23.71 μs'  │\n│     webcrypto sha1     │ '12.34 μs/iter' │ '9.04 μs' │ '852.58 μs' │\n│    node:crypto sha1    │ '3.48 μs/iter'  │ '2.83 μs' │ '88.50 μs'  │\n│ npm:@noble/hashes/sha1 │ '7.34 μs/iter'  │ '6.37 μs' │ '746.42 μs' │\n└────────────────────────┴─────────────────┴───────────┴─────────────┘\n\nSummary\n- wasm sha1 is 2.03x faster than WebCrypto\n- wasm sha1 is 0.57x faster than node:crypto\n- wasm sha1 is 1.21x faster than npm:@noble/hashes\n```\n\n### Keccak-256\n\n#### Deno\n\n```\n┌───────────────────┬─────────────────┬────────────┬─────────────┐\n│ (idx)             │ average         │ minimum    │ maximum     │\n├───────────────────┼─────────────────┼────────────┼─────────────┤\n│ wasm keccak256    │ \"4.91 μs/iter\"  │ \"4.37 μs\"  │ \"25.37 μs\"  │\n│ npm:@noble/hashes │ \"60.01 μs/iter\" │ \"57.83 μs\" │ \"195.50 μs\" │\n└───────────────────┴─────────────────┴────────────┴─────────────┘\n\nSummary\n- wasm keccak256 is 12.22x faster than npm:@noble/hashes\n```\n\n#### Node\n\n```\ncpu: Apple M1 Max\nruntime: node v20.3.1 (arm64-darwin)\n\n┌───────────────────┬─────────────────┬────────────┬─────────────┐\n│      (index)      │     average     │  minimum   │   maximum   │\n├───────────────────┼─────────────────┼────────────┼─────────────┤\n│  wasm keccak256   │ '3.10 μs/iter'  │ '2.92 μs'  │ '104.00 μs' │\n│ npm:@noble/hashes │ '62.28 μs/iter' │ '60.21 μs' │ '166.33 μs' │\n└───────────────────┴─────────────────┴────────────┴─────────────┘\n\nSummary\n- wasm keccak256 is 20.08x faster than npm:@noble/hashes\n```\n\n### CRC32\n\n#### Deno\n\n```\ncpu: Apple M1 Max\nruntime: deno 1.30.3 (arm64-darwin)\n\n┌────────────┬────────────────┬───────────┬─────────────┐\n│ (idx)      │ average        │ minimum   │ maximum     │\n├────────────┼────────────────┼───────────┼─────────────┤\n│ wasm crc32 │ \"3.04 μs/iter\" │ \"2.17 μs\" │ \"198.04 μs\" │\n│ npm:crc-32 │ \"4.36 μs/iter\" │ \"2.04 μs\" │ \"97.96 μs\"  │\n└────────────┴────────────────┴───────────┴─────────────┘\n\nSummary\n- wasm crc32 is 1.44x faster than npm:crc-32\n```\n\n#### Node\n\n```\ncpu: Apple M1 Max\nruntime: node v18.12.1 (arm64-darwin)\n\n┌────────────┬────────────────┬───────────┬────────────┐\n│  (index)   │    average     │  minimum  │  maximum   │\n├────────────┼────────────────┼───────────┼────────────┤\n│ wasm crc32 │ '2.40 μs/iter' │ '2.00 μs' │ '53.88 μs' │\n│ npm:crc-32 │ '3.73 μs/iter' │ '2.25 μs' │ '1.11 ms'  │\n└────────────┴────────────────┴───────────┴────────────┘\n\nSummary\n- wasm crc32 is 1.55x faster than npm:crc-32\n```\n\n## Usage\n\n### SHA-1 / SHA-256 / Keccak-256 / RIPEMD-160 (direct)\n\n```ts\nimport { Morax, sha1 } from \"@hazae41/morax\";\n\n// Wait for WASM to load\nawait Morax.initBundledOnce()\n\n// Data to be hashed\nconst hello = new TextEncoder().encode(\"Hello World\")\n\n// Grab the digest (Uint8Array)\nconst digest = sha1(hello).copyAndDispose()\n```\n\n### CRC32 (direct)\n\n```ts\nimport { Morax, crc32 } from \"@hazae41/morax\";\n\n// Wait for WASM to load\nawait Morax.initBundledOnce()\n\n// Data to be hashed\nconst hello = new TextEncoder().encode(\"Hello World\")\n\n// Grab the digest (number)\nconst digest = crc32(hello)\n```\n\n### SHA-1 / SHA-256 / Keccak-256 / RIPEMD-160 (incremental)\n\n```ts\nimport { Morax, Sha1Hasher } from \"@hazae41/morax\";\n\n// Wait for WASM to load\nawait Morax.initBundledOnce()\n\n// Create a hash\nconst hasher = new Sha1Hasher()\n\n// Data to be hashed\nconst hello = new TextEncoder().encode(\"Hello World\")\n\n// Update the hash with your data\nhasher.update(hello)\n\n// Grab the digest (Uint8Array)\nconst digest = hasher.finalize().copyAndDispose()\n\n// Update the hash another time\nhasher.update(hello)\n\n// Grab the digest (Uint8Array)\nconst digest2 = hasher.finalize().copyAndDispose()\n\n// digest !== digest2\nconsole.log(digest)\nconsole.log(digest2)\n\nhasher.free()\n```\n\n### CRC32 (incremental)\n\n```ts\nimport { Morax, Crc32Hasher } from \"@hazae41/morax\";\n\n// Wait for WASM to load\nawait Morax.initBundledOnce()\n\n// Create a hash\nconst hasher = new Crc32Hasher()\n\n// Data to be hashed\nconst hello = new TextEncoder().encode(\"Hello World\")\n\n// Update the hash with your data\nhasher.update(hello)\n\n// Grab the checksum (number)\nconst checksum = hasher.finalize()\n\n// Update the hash another time\nhasher.update(hello)\n\n// Grab the checksum (number)\nconst checksum2 = hasher.finalize()\n\n// checksum !== checksum2\nconsole.log(checksum)\nconsole.log(checksum2)\n\nhasher.free()\n```\n\n## Building\n\n### Unreproducible building\n\nYou need to install [Rust](https://www.rust-lang.org/tools/install)\n\nThen, install [wasm-pack](https://github.com/rustwasm/wasm-pack)\n\n```bash\ncargo install wasm-pack\n```\n\nFinally, do a clean install and build\n\n```bash\nnpm ci \u0026\u0026 npm run build\n```\n\n### Reproducible building\n\nYou can build the exact same bytecode using Docker, just be sure you're on a `linux/amd64` host\n\n```bash\ndocker compose up --build\n```\n\nThen check that all the files are the same using `git status`\n\n```bash\ngit status --porcelain\n```\n\nIf the output is empty then the bytecode is the same as the one I commited\n\n### Automated checks\n\nEach time I commit to the repository, the GitHub's CI does the following:\n- Clone the repository\n- Reproduce the build using `docker compose up --build`\n- Throw an error if the `git status --porcelain` output is not empty\n\nEach time I release a new version tag on GitHub, the GitHub's CI does the following:\n- Clone the repository\n- Do not reproduce the build, as it's already checked by the task above\n- Throw an error if there is a `npm diff` between the cloned repository and the same version tag on NPM\n\nIf a version is present on NPM but not on GitHub, do not use!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhazae41%2Fmorax","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhazae41%2Fmorax","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhazae41%2Fmorax/lists"}