{"id":15833820,"url":"https://github.com/itzmeanjan/grain-128aead","last_synced_at":"2025-04-01T12:26:58.986Z","repository":{"id":55060828,"uuid":"521937834","full_name":"itzmeanjan/grain-128aead","owner":"itzmeanjan","description":"Grain-128AEAD: A Lightweight AEAD Stream Cipher","archived":false,"fork":false,"pushed_at":"2022-09-07T08:50:56.000Z","size":173,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-10-06T13:42:41.682Z","etag":null,"topics":["aead","authenticated-encryption","grain-128a","grain-128aead","lightweight-cryptography","nist","nist-lwc","stream-cipher","verified-decryption"],"latest_commit_sha":null,"homepage":"","language":"C++","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}},"created_at":"2022-08-06T12:15:10.000Z","updated_at":"2022-09-26T07:12:52.000Z","dependencies_parsed_at":"2022-08-14T10:40:16.517Z","dependency_job_id":null,"html_url":"https://github.com/itzmeanjan/grain-128aead","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itzmeanjan%2Fgrain-128aead","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itzmeanjan%2Fgrain-128aead/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itzmeanjan%2Fgrain-128aead/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itzmeanjan%2Fgrain-128aead/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/itzmeanjan","download_url":"https://codeload.github.com/itzmeanjan/grain-128aead/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246638035,"owners_count":20809728,"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":["aead","authenticated-encryption","grain-128a","grain-128aead","lightweight-cryptography","nist","nist-lwc","stream-cipher","verified-decryption"],"created_at":"2024-10-05T13:42:42.341Z","updated_at":"2025-04-01T12:26:58.968Z","avatar_url":"https://github.com/itzmeanjan.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# grain-128aead\n\nGrain-128AEAD: A Lightweight AEAD Stream Cipher\n\n## Motivation\n\nGrain-128 AEAD is a lightweight AEAD ( authenticated encryption with associated data ) scheme, which is closely based on Grain-128a stream cipher, competing in final round of NIST Light Weight Cryptography ( LWC ) standardization effort. \n\n\u003e See NIST LWC finalists [here](https://csrc.nist.gov/Projects/lightweight-cryptography/finalists)\n\nGrain-128 AEAD offers only one authenticated encryption/ verified decryption with associated data algorithm, which has following interface\n\nRoutine | Input Interface | Output Interface\n--- | --- | ---\n`encrypt` | 16 -bytes secret key, 12 -bytes nonce, N -bytes associated data, M -bytes plain text | M -bytes cipher text, 8 -bytes authentication tag\n`decrypt` | 16 -bytes secret key, 12 -bytes nonce, 8 -bytes authentication tag, N -bytes associated data, M -bytes cipher text | M -bytes plain text, boolean verification flag\n\n\u003e In above table, N, M \u003e= 0\n\nHere, I present a header-only, zero-dependency, easy-to-use C++ library, implementing Grain-128 AEADv2, which is submitted to NIST LWC final round call, see [here](https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-submissions/grain-128aead.zip).\n\nDuring this work, I've followed Grain-128 AEADv2 specification, which I suggest you to go through, to have a better view of this AEAD scheme. Find specification document [here](https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/grain-128aead-spec-final.pdf).\n\nAlso note, this is the 10th ( i.e. last ) AEAD scheme, that I decided to implement as easy-to-use C++ library, which is competing in NIST LWC final round. Previous 9 AEAD schemes, that I worked on, can be found\n\n- [Ascon](https://github.com/itzmeanjan/ascon)\n- [TinyJambu](https://github.com/itzmeanjan/tinyjambu)\n- [Xoodyak](https://github.com/itzmeanjan/xoodyak)\n- [Sparkle](https://github.com/itzmeanjan/sparkle)\n- [Photon-Beetle](https://github.com/itzmeanjan/photon-beetle)\n- [ISAP](https://github.com/itzmeanjan/isap)\n- [Romulus](https://github.com/itzmeanjan/romulus)\n- [GIFT-COFB](https://github.com/itzmeanjan/gift-cofb)\n- [Elephant](https://github.com/itzmeanjan/elephant)\n\nA few things to note before moving forward\n\n- Asssociated data is never encrypted by AEAD scheme. Only plain text is encrypted while both associated data \u0026 plain text are authenticated.\n- Don't reuse same public message nonce, under same secret key.\n- If authentication check fails during decryption, unverified plain text is never released. Instead memory allocation for plain text is explicitly zeroed.\n\nFollow progress of NIST LWC standardization [here](https://csrc.nist.gov/Projects/lightweight-cryptography).\n\n## Prerequisites\n\n- C++ compiler such as `g++`/ `clang++`, with C++20 standard library\n\n```bash\n$ g++ --version\ng++ (Ubuntu 11.2.0-19ubuntu1) 11.2.0\n\n$ clang++ --version\nUbuntu clang version 14.0.0-1ubuntu1\nTarget: aarch64-unknown-linux-gnu\nThread model: posix\nInstalledDir: /usr/bin\n```\n\n- System development tools such as `make`, `cmake`, `git`\n\n```bash\n$ make --version\nGNU Make 3.81\n\n$ cmake --version\ncmake version 3.23.2\n```\n\n- For testing functional correctness of Grain-128 AEAD, you must have `python3`, `wget` \u0026 `unzip` installed\n\n```bash\n$ python3 --version\nPython 3.10.4\n\n$ wget --version\nGNU Wget 1.21.3 built on darwin21.3.0.\n\n$ unzip -v\nUnZip 6.00 of 20 April 2009\n```\n\n- For executing tests against Known Answer Tests ( KATs ), install Python dependencies\n\n```bash\npython3 -m pip install --user -r wrapper/python/requirements.txt\n```\n\n- For benchmarking Grain-128 AEAD on CPU systems, you need to have `google-benchmark`, globally installed; follow [this](https://github.com/google/benchmark/tree/60b16f1#installation)\n\n## Testing\n\nFor ensuring functional correctness of Grain-128 AEAD implementation, I use known answer tests provided with NIST final round submission package for Grain-128 AEAD, which can be downloaded from [here](https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-submissions/grain-128aead.zip)\n\nGiven 16 -bytes secret key, 12 -bytes public message nonce, N -bytes associated data \u0026 M -bytes plain text, I use Grain-128 `encrypt` routine for computing M -bytes cipher text \u0026 8 -bytes authentication tag. Now both cipher text and authentication tag are compared against known answer tests ( KATs ), which is provided in submission package. Finally to ensure correctness of `decrypt` routine, I try to decrypt cipher text back to plain text, while successfully passing authentication check.\n\nFor executing tests, issue\n\n```bash\nmake\n```\n\n## Benchmarking\n\nFor benchmarking Grain-128 AEAD routines, issue\n\n```bash\nmake benchmark\n```\n\n\u003e For disabling CPU scaling when benchmarking, see [this](https://github.com/google/benchmark/blob/60b16f1/docs/user_guide.md#disabling-cpu-frequency-scaling)\n\nNote that, when benchmarking, associated data length is always kept 32 -bytes, while variable length ( = L ) plain text is used | L ∈ [64..4096] \u0026\u0026 L = 2 ^ i.\n\n\u003e Note, in this implementation, 8/ 32 ( preferred ) consecutive cycles of Grain-128 AEAD stream cipher are executed in parallel, after cipher internal state is initialized. During execution of initialization phase, 32 consecutive clocks are executed in parallel ( initialization is done by clocking cipher state 512 times ).\n\n### On AWS Graviton3\n\n```bash\n2022-08-31T16:05:56+00:00\nRunning ./bench/a.out\nRun on (64 X 2100 MHz CPU s)\nCPU Caches:\n  L1 Data 64 KiB (x64)\n  L1 Instruction 64 KiB (x64)\n  L2 Unified 1024 KiB (x64)\n  L3 Unified 32768 KiB (x1)\nLoad Average: 0.00, 0.00, 0.00\n-----------------------------------------------------------------------------------------------\nBenchmark                                     Time             CPU   Iterations UserCounters...\n-----------------------------------------------------------------------------------------------\nbench_grain_128aead::encrypt/32/64         2260 ns         2260 ns       309684 bytes_per_second=40.5189M/s\nbench_grain_128aead::decrypt/32/64         2297 ns         2297 ns       304639 bytes_per_second=39.8507M/s\nbench_grain_128aead::encrypt/32/128        3459 ns         3459 ns       202384 bytes_per_second=44.1175M/s\nbench_grain_128aead::decrypt/32/128        3525 ns         3525 ns       198544 bytes_per_second=43.2822M/s\nbench_grain_128aead::encrypt/32/256        5862 ns         5862 ns       119396 bytes_per_second=46.8546M/s\nbench_grain_128aead::decrypt/32/256        5984 ns         5984 ns       117008 bytes_per_second=45.8975M/s\nbench_grain_128aead::encrypt/32/512       10672 ns        10672 ns        65566 bytes_per_second=48.6149M/s\nbench_grain_128aead::decrypt/32/512       10930 ns        10930 ns        64043 bytes_per_second=47.4664M/s\nbench_grain_128aead::encrypt/32/1024      20291 ns        20290 ns        34500 bytes_per_second=49.6335M/s\nbench_grain_128aead::decrypt/32/1024      20786 ns        20785 ns        33673 bytes_per_second=48.4518M/s\nbench_grain_128aead::encrypt/32/2048      39525 ns        39524 ns        17717 bytes_per_second=50.1878M/s\nbench_grain_128aead::decrypt/32/2048      40434 ns        40433 ns        17287 bytes_per_second=49.0603M/s\nbench_grain_128aead::encrypt/32/4096      78112 ns        78110 ns         8957 bytes_per_second=50.4003M/s\nbench_grain_128aead::decrypt/32/4096      79721 ns        79719 ns         8780 bytes_per_second=49.3829M/s\n```\n\n### On AWS Graviton2\n\n```bash\n2022-08-31T16:04:51+00:00\nRunning ./bench/a.out\nRun on (16 X 166.66 MHz CPU s)\nCPU Caches:\n  L1 Data 32 KiB (x16)\n  L1 Instruction 48 KiB (x16)\n  L2 Unified 2048 KiB (x4)\nLoad Average: 0.08, 0.02, 0.01\n-----------------------------------------------------------------------------------------------\nBenchmark                                     Time             CPU   Iterations UserCounters...\n-----------------------------------------------------------------------------------------------\nbench_grain_128aead::encrypt/32/64         3815 ns         3815 ns       183503 bytes_per_second=24.0005M/s\nbench_grain_128aead::decrypt/32/64         3959 ns         3959 ns       176836 bytes_per_second=23.1279M/s\nbench_grain_128aead::encrypt/32/128        5806 ns         5806 ns       120566 bytes_per_second=26.2823M/s\nbench_grain_128aead::decrypt/32/128        6061 ns         6061 ns       115485 bytes_per_second=25.1749M/s\nbench_grain_128aead::encrypt/32/256        9788 ns         9788 ns        71513 bytes_per_second=28.06M/s\nbench_grain_128aead::decrypt/32/256       10266 ns        10266 ns        68180 bytes_per_second=26.7538M/s\nbench_grain_128aead::encrypt/32/512       17753 ns        17753 ns        39429 bytes_per_second=29.2235M/s\nbench_grain_128aead::decrypt/32/512       18677 ns        18677 ns        37480 bytes_per_second=27.7779M/s\nbench_grain_128aead::encrypt/32/1024      33683 ns        33682 ns        20781 bytes_per_second=29.8993M/s\nbench_grain_128aead::decrypt/32/1024      35499 ns        35498 ns        19719 bytes_per_second=28.3703M/s\nbench_grain_128aead::encrypt/32/2048      65545 ns        65544 ns        10679 bytes_per_second=30.2645M/s\nbench_grain_128aead::decrypt/32/2048      69141 ns        69140 ns        10124 bytes_per_second=28.6903M/s\nbench_grain_128aead::encrypt/32/4096     129270 ns       129266 ns         5415 bytes_per_second=30.4548M/s\nbench_grain_128aead::decrypt/32/4096     136443 ns       136436 ns         5130 bytes_per_second=28.8542M/s\n```\n\n### On Intel(R) Core(TM) i5-8279U CPU @ 2.40GHz\n\n```bash\n2022-08-31T16:22:03+04:00\nRunning ./bench/a.out\nRun on (8 X 2400 MHz CPU s)\nCPU Caches:\n  L1 Data 32 KiB\n  L1 Instruction 32 KiB\n  L2 Unified 256 KiB (x4)\n  L3 Unified 6144 KiB\nLoad Average: 1.74, 1.65, 1.68\n-----------------------------------------------------------------------------------------------\nBenchmark                                     Time             CPU   Iterations UserCounters...\n-----------------------------------------------------------------------------------------------\nbench_grain_128aead::encrypt/32/64         1453 ns         1451 ns       466614 bytes_per_second=63.1063M/s\nbench_grain_128aead::decrypt/32/64         1462 ns         1461 ns       476547 bytes_per_second=62.6804M/s\nbench_grain_128aead::encrypt/32/128        2179 ns         2178 ns       318384 bytes_per_second=70.0644M/s\nbench_grain_128aead::decrypt/32/128        2169 ns         2168 ns       318480 bytes_per_second=70.3666M/s\nbench_grain_128aead::encrypt/32/256        3651 ns         3648 ns       190775 bytes_per_second=75.2873M/s\nbench_grain_128aead::decrypt/32/256        3632 ns         3629 ns       192214 bytes_per_second=75.6859M/s\nbench_grain_128aead::encrypt/32/512        6645 ns         6638 ns       103301 bytes_per_second=78.1543M/s\nbench_grain_128aead::decrypt/32/512        6540 ns         6534 ns       104490 bytes_per_second=79.4022M/s\nbench_grain_128aead::encrypt/32/1024      12507 ns        12502 ns        54486 bytes_per_second=80.5554M/s\nbench_grain_128aead::decrypt/32/1024      12421 ns        12412 ns        55613 bytes_per_second=81.1347M/s\nbench_grain_128aead::encrypt/32/2048      24295 ns        24281 ns        28632 bytes_per_second=81.6966M/s\nbench_grain_128aead::decrypt/32/2048      24457 ns        24436 ns        28425 bytes_per_second=81.1757M/s\nbench_grain_128aead::encrypt/32/4096      48003 ns        47955 ns        14618 bytes_per_second=82.0922M/s\nbench_grain_128aead::decrypt/32/4096      48276 ns        48254 ns        13964 bytes_per_second=81.5837M/s\n```\n\n### On Intel(R) Xeon(R) CPU E5-2686 v4 @ 2.30GHz\n\n```bash\n2022-08-31T12:28:04+00:00\nRunning ./bench/a.out\nRun on (4 X 2300 MHz CPU s)\nCPU Caches:\n  L1 Data 32 KiB (x2)\n  L1 Instruction 32 KiB (x2)\n  L2 Unified 256 KiB (x2)\n  L3 Unified 46080 KiB (x1)\nLoad Average: 0.33, 0.10, 0.03\n-----------------------------------------------------------------------------------------------\nBenchmark                                     Time             CPU   Iterations UserCounters...\n-----------------------------------------------------------------------------------------------\nbench_grain_128aead::encrypt/32/64         3619 ns         3619 ns       195348 bytes_per_second=25.2991M/s\nbench_grain_128aead::decrypt/32/64         3789 ns         3789 ns       184952 bytes_per_second=24.1653M/s\nbench_grain_128aead::encrypt/32/128        5232 ns         5232 ns       133591 bytes_per_second=29.1669M/s\nbench_grain_128aead::decrypt/32/128        5621 ns         5621 ns       124339 bytes_per_second=27.1447M/s\nbench_grain_128aead::encrypt/32/256        8499 ns         8499 ns        82400 bytes_per_second=32.3173M/s\nbench_grain_128aead::decrypt/32/256        9139 ns         9139 ns        76565 bytes_per_second=30.0546M/s\nbench_grain_128aead::encrypt/32/512       15039 ns        15037 ns        46525 bytes_per_second=34.5006M/s\nbench_grain_128aead::decrypt/32/512       16307 ns        16306 ns        42871 bytes_per_second=31.8155M/s\nbench_grain_128aead::encrypt/32/1024      28187 ns        28184 ns        24827 bytes_per_second=35.7327M/s\nbench_grain_128aead::decrypt/32/1024      30596 ns        30595 ns        22879 bytes_per_second=32.9164M/s\nbench_grain_128aead::encrypt/32/2048      54417 ns        54417 ns        12864 bytes_per_second=36.4529M/s\nbench_grain_128aead::decrypt/32/2048      59023 ns        59020 ns        11836 bytes_per_second=33.6099M/s\nbench_grain_128aead::encrypt/32/4096     106662 ns       106663 ns         6572 bytes_per_second=36.9085M/s\nbench_grain_128aead::decrypt/32/4096     116021 ns       116022 ns         6030 bytes_per_second=33.9313M/s\n```\n\n## Usage\n\nGrain-128 AEAD is written such that it's pretty easy to start using in your project. All that is required is\n\n- Include `./include/grain_128aead.hpp` header file in your source\n- Use `encrypt`/ `decrypt` routines defined under namespace `grain_128aead`\n- Let your compiler know where to find these header files ( i.e. `./include` directory )\n\nFor API documentation, I suggest you read through\n\n- [encrypt( ... )](https://github.com/itzmeanjan/grain-128aead/blob/55539e43c5d3b5c098944706a8855ae226546593/include/grain_128aead.hpp#L7-L21)\n- [decrypt( ... )](https://github.com/itzmeanjan/grain-128aead/blob/55539e43c5d3b5c098944706a8855ae226546593/include/grain_128aead.hpp#L43-L56)\n\nI keep API usage example [here](./example/main.cpp).\n\n```bash\nGrain-128 AEAD\n\nKey       : 08ecc6d3edaa57cbdf4bd4b6f43869fa\nNonce     : f8f755034bff227fa107fac0\nData      : f7b04b12051680d1af943e142e9e0e95e24c6bdf753edb4aa12480cc8d179ca5\nText      : 38937413bedf5c753d0eaebc61467b814b4e6e9d6c1ab6ec4fbde192e4581afa\nEncrypted : 1cb5edd9aed81348df76ad4c197322daa0ec40f92020725d62fd52edf61906c9\nDecrypted : 38937413bedf5c753d0eaebc61467b814b4e6e9d6c1ab6ec4fbde192e4581afa\nTag       : 1cb420123b94d3a7\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitzmeanjan%2Fgrain-128aead","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fitzmeanjan%2Fgrain-128aead","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitzmeanjan%2Fgrain-128aead/lists"}