{"id":19620658,"url":"https://github.com/nakov/nakov-simple-crypto","last_synced_at":"2025-04-28T03:32:08.828Z","repository":{"id":146213215,"uuid":"603836824","full_name":"nakov/Nakov-Simple-Crypto","owner":"nakov","description":"Simple Crypto Algorithms: 32-Bit Hash and 32-Bit Symmetric Block Cypher","archived":false,"fork":false,"pushed_at":"2023-04-06T11:19:33.000Z","size":110,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-05T05:51:12.114Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nakov.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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-02-19T18:00:08.000Z","updated_at":"2024-12-31T01:25:20.000Z","dependencies_parsed_at":null,"dependency_job_id":"ff6a76cf-2261-4b7f-9179-504355faec10","html_url":"https://github.com/nakov/Nakov-Simple-Crypto","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/nakov%2FNakov-Simple-Crypto","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nakov%2FNakov-Simple-Crypto/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nakov%2FNakov-Simple-Crypto/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nakov%2FNakov-Simple-Crypto/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nakov","download_url":"https://codeload.github.com/nakov/Nakov-Simple-Crypto/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251246155,"owners_count":21558759,"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":[],"created_at":"2024-11-11T11:19:35.479Z","updated_at":"2025-04-28T03:32:08.821Z","avatar_url":"https://github.com/nakov.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Nakov's Simple Crypto Algorithms\n\nSimple crypto algorithms, designed for educational purposes:\n  - 32-bit low-collision **hash function**\n  - 32-bit **symmetric block cipher**\n\n\n## Simple 32-Bit Hash + Symmetric Encryption Algorithm\n\nThis project demonstrates how to build a **simple 32-bit crypto hashing function** and a **symmetric 32-bit block cipher** (encrypt + decrypt).\n\n\n### How Does It Work?\n\nThe algorithms are based on a simple **[Merkle–Damgård construction](https://en.wikipedia.org/wiki/Merkle%E2%80%93Damg%C3%A5rd_construction)**\nusing 32-bit blocks.\n\n\n### Designing a Padding Scheme\n\nHashing and encryption typically work on **blocks of fixes size**, e.g. 32-bits (4 bytes).\nWhen the input message size is not multiple of the block size, we need to **pad the message** with additional chars at the end.\n\nWe use the following **padding scheme**:\n```\nmsg + 0...3 times \"*\" + msg_length\n```\n\nExamples:\n  - `ab` --\u003e `ab*2` (1 block)\n  - `abcdefg` --\u003e `abcdefg7` (2 blocks)\n  - `a` --\u003e `a**1` (1 block)\n  - `a**` --\u003e `a**3` (1 block)\n  - `abcdedghi` --\u003e `abcdedghi**9` (3 blocks)\n\nWe append the message length at the end to avoid trivial collision construction schemes.\n\nWarning: more simple padding schemes (e.g. just add a few \"*\" at the end) may be insecure for using with hash functions,\ndue to **[collision attack](https://en.wikipedia.org/wiki/Collision_attack)** and\n**[length-extension attack](https://en.wikipedia.org/wiki/Length_extension_attack)** vulnerabilities.\n\n\n### Designing a Simple Crypto Hash Function\n\nWe follow the classical **[Merkle–Damgård construction scheme](https://en.wikipedia.org/wiki/Merkle%E2%80%93Damgard_construction)**\nto build two cryptographic primitives `MixBlocks(block, state)` and `Hash(msg)`.\n\nThe **block mixing** primitive works as follows:\n\n```\nMixBlocks(block, state) --\u003e new state:\n    repeat 16 times:\n        state = state * 28657 + block * 514229 + 2971215073\n        block = block * 1597 + 433494437\n        state = state \u003c\u003c\u003c 7\n        block = block \u003e\u003e\u003e  13\n    return state\n```\n\nNotes:\n  - The magic numbers above are **prime numbers** (to reduce potential collissions).\n  - The above design aims to make the function **irreversible**, while **preserving the entropy** from the input blocks.\n\nThe **hash calculation** primitive follows the classical **[Merkle–Damgård construction](https://en.wikipedia.org/wiki/Merkle%E2%80%93Damgard_construction)** over the input sequence of blocks using the **block mixing** primitive:\n\n```\nHash(msg) --\u003e int32:\n    msg = PadMsg(msg)   // Make the message size a multiple of 32-bits\n    state = 0xA1B2C3D4  // Initial Vector (IV): a magic number\n    for each 32-bit block from the input message:\n        state = MixBlocks(block, state)\n    return state  \n```\n\n\n### Designing a Simple Symmetric Encryption Scheme\n\nWe propose a **simple symmetric block cipher**, based on `XOR` or each letter from the input message with an **unique sequence of hash values**, derived from the **encryption password**, the **character offset** in the input message and the **input message** itself.\n\n### Encryption Algorithm\n\nOnce we have a collision-resistant cryptographic hash function, we may design a **simple symmetric encryption scheme** as follows:\n\n```\nEncrypt(msg, password):\n    msgHash = Hash(msg)\n    for i = 0 ... msg_length-1:\n        encryptedChar[i] = msg[i] xor Hash(i + \" | \" + password + \" | \" + msgHash)\n    return msgHash + encrypted chars\n```\n\nWe encrypt each letter from the input sequence by an **unique and hard-to-predict hash value**,\nderived from: `letter offset` + `input password` + `message hash`.\n\nThe letter encryption is based on **bitwise `XOR`**, so it is easy to revert back to the original letter\nwhen we know the encrypted letter and the encryption hash value for this letter.\n\nExample:\n  - Suppose we have a message msg = `hello` to be encrypted by a password `p@ss`\n  - The message hash will be calculated as `57A97ED8`\n  - Each message letter will be encrypted by different hash, derived from the letter offset + password + msgHash:\n    - encryptedChar[`0`] = `h` xor Hash(`0 | p@ss | 57A97ED8`) = `01FF`\n    - encryptedChar[`1`] = `e` xor Hash(`1 | p@ss | 57A97ED8`) = `A0A9`\n    - encryptedChar[`2`] = `l` xor Hash(`2 | p@ss | 57A97ED8`) = `79A5`\n    - encryptedChar[`3`] = `l` xor Hash(`3 | p@ss | 57A97ED8`) = `8F72`\n    - encryptedChar[`4`] = `o` xor Hash(`4 | p@ss | 57A97ED8`) = `B4DF`\n  - encryptedMsg = `57A97ED8` + `01FF` + `A0A9` + `79A5` + `8F72` + `B4DF` = `57A97ED801FFA0A979A58F72B4DF`\n\nThe above encryption scheme design aims to generate an unique and hard-to-predict **encryption hash sequence**,\nwhich depends highly on the input message and the encryption password. The security of the algorithm relies on\nthe difficulty to generate the same **encryption hash sequence** without knowing the encryption password.\n\nThe reason to include the **input message hash** in the calculation of the encryption hash sequence is to avoid\n**revealing the encryption hash sequence** when we know a significant part of the encrypted message (e.g. its first paragraph)\nand we use the same password to encrypt multiple messages (e.g. 50 text files in an encrypted ZIP archive).\n\n### Decryption Algorithm\n\nDecryption follows the same scheme, like the encryption:\n\n```\nDecrypt(encryptedMsg, password):\n    msgHash = extract and remove the first 8 letters from encryptedMsg\n    for i = 0 ... msg_length-1:\n        decryptedChar[i] = substring(encryptedMsg, i*4, 4) xor Hash(i + \" | \" + password + \" | \" + msgHash)\n    return decrypted chars\n```\n\nExample:\n  - Suppose encryptedMsg = `57A97ED801FFA0A979A58F72B4DF` and password = `p@ss`\n  - The encrypted message can be decomposed to:\n    - `57A97ED8` (msgHash) + `01FF` (char 0) + `A0A9` (char 1) + `79A5` (char 2) + `8F72` (char 3) + `B4DF` (char 4)\n  - To decrypt the encrypted message we XOR it with the same encryption hash sequence, used during the encryption:\n    - decryptedChar[`0`] = `01FF` xor Hash(`0 | p@ss | 57A97ED8`) = `h`\n    - decryptedChar[`1`] = `A0A9` xor Hash(`1 | p@ss | 57A97ED8`) = `e`\n    - decryptedChar[`2`] = `79A5` xor Hash(`2 | p@ss | 57A97ED8`) = `l`\n    - decryptedChar[`3`] = `8F72` xor Hash(`3 | p@ss | 57A97ED8`) = `l`\n    - decryptedChar[`4`] = `B4DF` xor Hash(`4 | p@ss | 57A97ED8`) = `o`\n  - The decrypted message = `h` + `e` + `l` + `l` + `o`\n\nNote that the above encryption scheme cannot detect if the password is correct or not.\nWhen we decrypt an encrypted message by a wrong password, we will get an incorrect output message.\n\nTo detect a wrong decryption password, we may add a **[message authentication code (MAC)](https://cryptobook.nakov.com/mac-and-key-derivation)** to the encrypted message.\n\n\n### Warning: Insecure for Cryptographic Use\n\nThis code library is **cryptographically insecure**. Don't use in production!\n\nUse this code **for educational purposes only**: to demonstrate some ideas about\nhow hashing and symetric encryption algorithms may be designed.\n\nNote also that **32-bit ciphers are too weak** for real-world crypto hashing and encryption.\nReal-world cryptosystems use blocks of size 256 or more bits to resist **[brute-force attacks](https://en.wikipedia.org/wiki/Brute-force_attack)**.\n\nDesigning your **own encryption algorithms** is risky and **prone to security flaws**. To design secure crypto algorithms, you need to have\ndeep specialized scientific knowledge, and your algorithms should pass peer reviews, thorough testing, and prove resistance against attacks.\n\nAlways use **proven crypto algorithms** (like SHA2, SHA3 and AES), designed by well-established experts in cryptography.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnakov%2Fnakov-simple-crypto","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnakov%2Fnakov-simple-crypto","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnakov%2Fnakov-simple-crypto/lists"}