{"id":15833687,"url":"https://github.com/itzmeanjan/multimixer-128","last_synced_at":"2026-01-21T14:01:48.855Z","repository":{"id":198859229,"uuid":"701635435","full_name":"itzmeanjan/multimixer-128","owner":"itzmeanjan","description":"Multimixer-128: Universal Keyed Hashing Based on Integer Multiplication","archived":false,"fork":false,"pushed_at":"2023-11-25T15:54:46.000Z","size":2446,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-28T22:30:50.262Z","etag":null,"topics":["f-128","hashing","keyed-hashing","message-authentication-code","multimixer-128","universal-hashing"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/itzmeanjan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-10-07T05:54:06.000Z","updated_at":"2025-11-20T06:16:27.000Z","dependencies_parsed_at":"2023-11-09T11:15:59.481Z","dependency_job_id":"a1eb1f0c-9589-4d1e-966c-f12615a07e1e","html_url":"https://github.com/itzmeanjan/multimixer-128","commit_stats":null,"previous_names":["itzmeanjan/multimixer-128"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/itzmeanjan/multimixer-128","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itzmeanjan%2Fmultimixer-128","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itzmeanjan%2Fmultimixer-128/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itzmeanjan%2Fmultimixer-128/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itzmeanjan%2Fmultimixer-128/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/itzmeanjan","download_url":"https://codeload.github.com/itzmeanjan/multimixer-128/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itzmeanjan%2Fmultimixer-128/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28634786,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-21T04:47:28.174Z","status":"ssl_error","status_checked_at":"2026-01-21T04:47:22.943Z","response_time":86,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["f-128","hashing","keyed-hashing","message-authentication-code","multimixer-128","universal-hashing"],"created_at":"2024-10-05T13:41:37.036Z","updated_at":"2026-01-21T14:01:48.839Z","avatar_url":"https://github.com/itzmeanjan.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# multimixer-128\nMultimixer-128: Universal Keyed Hashing Based on Integer Multiplication\n\n## Overview\n\n$Multimixer_{128}$ is a universal keyed hashing algorithm, based on just integer arithmetic ( addition and multiplication ), proposed in paper https://ia.cr/2023/1357. \n\nA keyed hash function, takes a key and a variable length message as input, compressing it to a fixed length digest. The keyed hashing scheme proposed in $Multimixer_{128}$ paper, takes equal length key and message ( meaning long keys will be required, in case message is long ) s.t. they are multiple of block size ( = 32 -bytes ) and compresses them into a 64 -bytes digest. It's proved to be an ε-∆universal hash function with ε = $2^{−127}$. It can be used during the compression phase of a message authentication code computation scheme. It can also be used in the compression phase of the Farfalle construction - which are used for building deck functions.\n\nAs $Multimixer_{128}$ is just based on integer arithmetic, which is pretty fast on most processors, it shows quite promising results during benchmarks. See [below](#benchmarking).\n\nYou can also find more details on how to start using $Multimixer_{128}$ API, [below](#usage).\n\n## Prerequisites\n\nRust stable toolchain; see https://rustup.rs for installation guide.\n\n```bash\n# When developing this library, I was using\n$ rustc --version\nrustc 1.73.0 (cc66ad468 2023-10-03)\n```\n\u003e [!TIP]\nI advise you to use `cargo-criterion` for running benchmark executable. Read more about it @ https://crates.io/crates/cargo-criterion. You can just issue following command for installing it system-wide.\n\n```bash\ncargo install cargo-criterion\n```\n\n## Testing\n\nFor ensuring functional correctness and conformance to the specification of $Multimixer_{128}$ i.e. https://ia.cr/2023/1357 ( and its reference implementation https://github.com/Parisaa/Multimixer ), I use known answer tests that I've generated by following instructions described in https://gist.github.com/itzmeanjan/a32eab0244af55eba2847c6472337535.\n\n```bash\ncargo test --lib\n```\n\n## Benchmarking\n\nIssue following command for benchmarking public function $f_{128}$ and $Multimixer_{128}$, with variable ( non-zero multiple of 32 -bytes ) length input key and message, on target CPU.\n\n\u003e [!NOTE]\n\u003e When benchmarking on `x86`, `x86_64`, `aarch64` or `loongarch64` targets, CPU cycles and cycles/ byte metrics are reported, while for other targets, default wallclock timer of criterion.rs is used for reporting time and throughput. I found https://github.com/pornin/crrl/blob/73b33c1efc73d637f3084d197353991a22c10366/benches/util.rs pretty useful for obtaining CPU cycles when benchmarking Rust functions. But I'm using criterion.rs as benchmark harness, hence I decided to go with https://crates.io/crates/criterion-cycles-per-byte plugin, much easier to integrate. But I had to patch it for my usecase and they live in the branch `add-memfence` of my fork of `criterion-cycles-per-byte` ( see my commits @ https://github.com/itzmeanjan/criterion-cycles-per-byte/commits/add-memfence ).\n\n\u003e [!NOTE]\n\u003e In case you're running benchmarks on aarch64 target, consider reading https://github.com/itzmeanjan/criterion-cycles-per-byte/blob/d2f5bf8638640962a9b301966dbb3e65fbc6f283/src/lib.rs#L63-L70.\n\n\u003e [!CAUTION]\n\u003e When benchmarking make sure you've disabled CPU frequency scaling, otherwise numbers you see can be pretty misleading. I found https://github.com/google/benchmark/blob/b40db869/docs/reducing_variance.md helpful.\n\n```bash\n# In case you didn't install `cargo-criterion`, you have to run benchmark with\n# RUSTFLAGS=\"-C opt-level=3 -C target-cpu=native\" cargo bench --features=\"internal\"\n\nRUSTFLAGS=\"-C opt-level=3 -C target-cpu=native\" cargo criterion --features=\"internal\"\n```\n\n### On *12th Gen Intel(R) Core(TM) i7-1260P*\n\n```bash\nf_128/f-128 (cached)    time:   [6.9927 cycles 7.0443 cycles 7.1069 cycles]                      \n                        thrpt:  [0.2221 cpb 0.2201 cpb 0.2185 cpb]\nf_128/f-128 (random)    time:   [21.1852 cycles 21.3297 cycles 21.4551 cycles]                   \n                        thrpt:  [0.6705 cpb 0.6666 cpb 0.6620 cpb]\n\nmultimixer_128/32B key/ msg (cached)                                                                             \n                        time:   [14.0913 cycles 14.1296 cycles 14.1664 cycles]\n                        thrpt:  [0.2214 cpb 0.2208 cpb 0.2202 cpb]\nmultimixer_128/32B key/ msg (random)                                                                            \n                        time:   [63.4513 cycles 63.8913 cycles 64.3942 cycles]\n                        thrpt:  [1.0062 cpb 0.9983 cpb 0.9914 cpb]\n\nmultimixer_128/128B key/ msg (cached)                                                                             \n                        time:   [42.2552 cycles 42.2975 cycles 42.3421 cycles]\n                        thrpt:  [0.1654 cpb 0.1652 cpb 0.1651 cpb]\nmultimixer_128/128B key/ msg (random)                                                                            \n                        time:   [107.6240 cycles 109.1370 cycles 111.0124 cycles]\n                        thrpt:  [0.4336 cpb 0.4263 cpb 0.4204 cpb]\n\nmultimixer_128/512B key/ msg (cached)                                                                            \n                        time:   [166.6061 cycles 166.8388 cycles 167.0822 cycles]\n                        thrpt:  [0.1632 cpb 0.1629 cpb 0.1627 cpb]\nmultimixer_128/512B key/ msg (random)                                                                            \n                        time:   [239.1786 cycles 240.4487 cycles 241.9385 cycles]\n                        thrpt:  [0.2363 cpb 0.2348 cpb 0.2336 cpb]\n\nmultimixer_128/2048B key/ msg (cached)                                                                            \n                        time:   [606.0156 cycles 606.3316 cycles 606.6701 cycles]\n                        thrpt:  [0.1481 cpb 0.1480 cpb 0.1480 cpb]\nmultimixer_128/2048B key/ msg (random)                                                                             \n                        time:   [835.5582 cycles 848.0583 cycles 859.5641 cycles]\n                        thrpt:  [0.2099 cpb 0.2070 cpb 0.2040 cpb]\n\nmultimixer_128/8192B key/ msg (cached)                                                                             \n                        time:   [2346.9930 cycles 2347.5554 cycles 2348.2118 cycles]\n                        thrpt:  [0.1433 cpb 0.1433 cpb 0.1432 cpb]\nmultimixer_128/8192B key/ msg (random)                                                                             \n                        time:   [2816.3210 cycles 2838.9367 cycles 2859.1557 cycles]\n                        thrpt:  [0.1745 cpb 0.1733 cpb 0.1719 cpb]\n```\n\n### On *ARM Cortex-A72 i.e. Raspberry Pi 4B*\n\n```bash\nf_128/f-128 (cached)    time:   [33.5869 cycles 33.6835 cycles 33.7842 cycles]                   \n                        thrpt:  [1.0558 cpb 1.0526 cpb 1.0496 cpb]\nf_128/f-128 (random)    time:   [118.9137 cycles 119.6657 cycles 120.5443 cycles]               \n                        thrpt:  [3.7670 cpb 3.7396 cpb 3.7161 cpb]\n\nmultimixer_128/32B key/ msg (cached)                                                                            \n                        time:   [189.0723 cycles 189.1691 cycles 189.2789 cycles]\n                        thrpt:  [2.9575 cpb 2.9558 cpb 2.9543 cpb]\nmultimixer_128/32B key/ msg (random)                                                                             \n                        time:   [433.4768 cycles 436.1863 cycles 438.5723 cycles]\n                        thrpt:  [6.8527 cpb 6.8154 cpb 6.7731 cpb]\n\nmultimixer_128/128B key/ msg (cached)                                                                            \n                        time:   [699.8622 cycles 699.9601 cycles 700.0751 cycles]\n                        thrpt:  [2.7347 cpb 2.7342 cpb 2.7338 cpb]\nmultimixer_128/128B key/ msg (random)                                                                             \n                        time:   [978.8853 cycles 979.8636 cycles 980.9012 cycles]\n                        thrpt:  [3.8316 cpb 3.8276 cpb 3.8238 cpb]\n\nmultimixer_128/512B key/ msg (cached)                                                                             \n                        time:   [2742.5257 cycles 2743.5495 cycles 2744.8465 cycles]\n                        thrpt:  [2.6805 cpb 2.6792 cpb 2.6782 cpb]\nmultimixer_128/512B key/ msg (random)                                                                             \n                        time:   [3223.0299 cycles 3228.1490 cycles 3233.4994 cycles]\n                        thrpt:  [3.1577 cpb 3.1525 cpb 3.1475 cpb]\n\nmultimixer_128/2048B key/ msg (cached)                                                                             \n                        time:   [10932.5461 cycles 10935.6646 cycles 10939.9686 cycles]\n                        thrpt:  [2.6709 cpb 2.6698 cpb 2.6691 cpb]\nmultimixer_128/2048B key/ msg (random)                                                                             \n                        time:   [12448.8476 cycles 12496.1792 cycles 12541.6384 cycles]\n                        thrpt:  [3.0619 cpb 3.0508 cpb 3.0393 cpb]\n\nmultimixer_128/8192B key/ msg (cached)                                                                             \n                        time:   [44770.5750 cycles 44779.3846 cycles 44790.3585 cycles]\n                        thrpt:  [2.7338 cpb 2.7331 cpb 2.7326 cpb]\nmultimixer_128/8192B key/ msg (random)                                                                             \n                        time:   [45914.0882 cycles 45978.0062 cycles 46044.7573 cycles]\n                        thrpt:  [2.8103 cpb 2.8063 cpb 2.8024 cpb]\n```\n\n## Usage\n\nUsing $Multimixer_{128}$ hasher API is pretty straight-forward.\n\n1) Add `multimixer-128` to the *[dependencies]* section of the Cargo.toml file of your project.\n\n```toml\n[dependencies]\nmultimixer-128 = { git = \"https://github.com/itzmeanjan/multimixer-128\" }\n# or\nmultimixer-128 = \"0.1.4\"\n\n# In case you're also interested in using f_128, the public function of multimixer-128,\n# enable `internal` feature-gate of this crate.\n#\n# multimixer-128 = { version = \"0.1.4\", features = \"internal\" }\n```\n\n2) Get non-zero, equal length key and message s.t. their byte length is a multiple of block size (= 32 -bytes), as input.\n\n```rust\nuse multimixer_128;\n\nfn main() {\n    const BLOCKS: usize = 1;\n    const MLEN: usize = multimixer_128::BLOCK_SIZE * BLOCKS;\n\n    // Beware, this is just an example key !\n    let key = [0x0fu8; MLEN];\n    let msg = [0xf0u8; MLEN];\n    let mut dig = [0u8; multimixer_128::DIGEST_SIZE];\n\n    // ...\n}\n```\n\n3) Compute 64 -bytes message digest, given equal length (non-zero) key and message.\n\n```rust\nfn main() {\n    // ...\n\n    multimixer_128::multimixer_128(\u0026key, \u0026msg, \u0026mut dig);\n    assert_eq!(dig, [1, 0, 0, 0, 254, 255, 255, 255, 1, 0, 0, 0, 254, 255, 255, 255, 1, 0, 0, 0, 254, 255, 255, 255, 1, 0, 0, 0, 254, 255, 255, 255, 9, 0, 0, 0, 250, 255, 255, 255, 9, 0, 0, 0, 250, 255, 255, 255, 9, 0, 0, 0, 250, 255, 255, 255, 9, 0, 0, 0, 250, 255, 255, 255]);\n}\n```\n\nI'm maintaining an example program, demonstrating usage of $Multimixer_{128}$ API, living inside [examples](./examples/) directory.\n\n```bash\ncargo run --example multimixer_128\n\nKey     = e02f28d290bd51df3b103396debe7f2ffc90b837588e37b13a7cc8cccce9fa11\nMessage = 1511ad54daae3df6706e33d9953f5dff4eabb2da85ad1added1aba2e0b571397\nDigest  = d2324595d842cb028205c1f00328ba760d292a690452726d95728070ee7ff21e8e6af14b1e4c6d15404e709fd1fec952da3e3b7b3fe7d038fca793f3b4d7661a\n```\n\n\u003e [!NOTE]\n\u003e Most of the internal functions of this library crate are implemented as `const fn` i.e. compile-time evaluable functions. That's why I also maintain another example [f_128.rs](./examples/f_128.rs) which demonstrates that property of this library using static assertions. Try executing the example program by issuing `$ cargo run --example f_128 --features=\"internal\"` and you'll see it.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitzmeanjan%2Fmultimixer-128","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fitzmeanjan%2Fmultimixer-128","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitzmeanjan%2Fmultimixer-128/lists"}