{"id":16759564,"url":"https://github.com/cyrildever/feistel-jar","last_synced_at":"2026-02-19T19:32:28.317Z","repository":{"id":45432239,"uuid":"355095676","full_name":"cyrildever/feistel-jar","owner":"cyrildever","description":"Feistel cipher implementation for the JVM providing format-preserving encryption","archived":false,"fork":false,"pushed_at":"2025-01-28T09:06:56.000Z","size":47873,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-04T04:39:01.103Z","etag":null,"topics":["algorithm","cryptography","encryption","feistel-cipher","format-preserving-encryption","fpe","xor-operation"],"latest_commit_sha":null,"homepage":"","language":"Scala","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/cyrildever.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":"2021-04-06T07:21:11.000Z","updated_at":"2025-01-28T09:07:00.000Z","dependencies_parsed_at":"2023-11-30T10:28:39.726Z","dependency_job_id":"84f6e527-d84e-49f1-a847-058c28281182","html_url":"https://github.com/cyrildever/feistel-jar","commit_stats":null,"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"purl":"pkg:github/cyrildever/feistel-jar","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cyrildever%2Ffeistel-jar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cyrildever%2Ffeistel-jar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cyrildever%2Ffeistel-jar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cyrildever%2Ffeistel-jar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cyrildever","download_url":"https://codeload.github.com/cyrildever/feistel-jar/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cyrildever%2Ffeistel-jar/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29628808,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-19T18:02:07.722Z","status":"ssl_error","status_checked_at":"2026-02-19T18:01:46.144Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6: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":["algorithm","cryptography","encryption","feistel-cipher","format-preserving-encryption","fpe","xor-operation"],"created_at":"2024-10-13T04:08:28.148Z","updated_at":"2026-02-19T19:32:28.299Z","avatar_url":"https://github.com/cyrildever.png","language":"Scala","funding_links":[],"categories":[],"sub_categories":[],"readme":"# feistel-jar\n\n![GitHub tag (latest by date)](https://img.shields.io/github/v/tag/cyrildever/feistel-jar)\n![GitHub last commit](https://img.shields.io/github/last-commit/cyrildever/feistel-jar)\n![GitHub issues](https://img.shields.io/github/issues/cyrildever/feistel-jar)\n![GitHub license](https://img.shields.io/github/license/cyrildever/feistel-jar)\n\nThis is a Scala library and JVM executable implementing the Feistel cipher for Format-Preserving Encryption (FPE).\n\n### Motivation\n\nThe main objective of this library is not to provide a secure encryption scheme but rather a safe obfuscation tool with format-preserving.\n\n\n### Formal description\n\nThis library operates on the concept of the Feistel cipher described in [Wikipedia](https://en.wikipedia.org/wiki/Feistel_cipher) as:\n\u003e A Feistel network is subdivided into several rounds or steps. In its balanced version, the network processes the data in two parts of identical size. On each round, the two blocks are exchanged, then one of the blocks is combined with a transformed version of the other block.\n\u003e Half of the data is encoded with the key, then the result of this operation is added using an XOR operation to the other half of the data.\n\u003e Then in the next round, we reverse: it is the turn of the last half to be encrypted and then to be xored to the first half, except that we use the data previously encrypted.\n\u003e The diagram below shows the data flow (the ${\\oplus}$ represents the XOR operation). Each round uses an intermediate key, usually taken from the main key via a generation called key schedule. The operations performed during encryption with these intermediate keys are specific to each algorithm.\n\n![](assets/400px-Feistel_cipher_diagram_en.svg.png)\n\nThe algorithmic description (provided by Wikipedia) of the encryption is as follows:\n* Let $n+1$ be the number of steps, $K_{0},K_{1},...,K_{n}$ the keys associated with each step and $F:\\Omega\\times\\mathcal{K}\\mapsto\\Omega$ a function of the $(words{\\times}keys)$ space to the $words$ space.\n* For each step $i{\\in}[0;n]$, note the encrypted word in step $i,m_{i}=L_{i}||R_{i}$:\n  * $L_{i+1}=R_{i}$\n  * $R_{i+1}=L_{i}{\\oplus}F(L_{i},K_{i})$\n* $m_{0}=L_{0}||R_{0}$ is the unciphered text, $m_{n+1}=L_{n+1}||R_{n+1}$ is the ciphered word. \n\nThere is no restriction on the $F$ function other than the XOR operation must be possible. For simplicity, we will choose $L_1$ of the same size as $R_1$ and the function $F$ shall transform a word of length $k$ into a word of length $k$ (and this for all $k$).\n\n\n### Usage\n\n#### Executable\n\nYou may use the JAR as a stand alone application on the command line:\n```\nfeistel-jar 1.5.7\nUsage: java -cp feistel-jar_2.12-1.5.7.jar com.cyrildever.feistel.Main [options] \u003cinput\u003e\n\n  -d, --decrypt            add to deobfuscate the passed input\n  -h, --hashEngine \u003cvalue\u003e\n                           the hash engine for the round function (default SHA-256)\n  -r, --rounds \u003cvalue\u003e     the number of rounds for the Feistel cipher (default 10)\n  -k, --key \u003cvalue\u003e        the optional key for the FPE scheme (leave it empty to use default)\n  -o, --output \u003cvalue\u003e     the optional name of the output file\n  \u003cinput\u003e                  the data to process\n```\neg.\n```console\n$ java -cp path/to/feistel-jar_2.12-1.5.7.jar com.cyrildever.feistel.Main 'myWordToObfuscate'\n```\n\n#### Library\n\nIn a Scala 2.12 project:\n```sbt\nlibraryDependencies += \"com.cyrildever\" %% \"feistel-jar\" % \"1.5.7\"\n```\n\nTo get an obfuscated string from a source data using an automatic key generation from SHA-256 hashing function at each round, first instantiate a `Feistel.FPECipher`, passing it a hash engine, a base key and a number of rounds.\nThen, use the `encrypt()` method with the source data as argument. The result will be a readable custom Base-256 string.\nTo ensure maximum security, I recommend you use a 256-bit key or longer and a minimum of 10 rounds.\nYou may use either of the following hash engine:\n- `Blake2b-256`;\n- `Keccak-256`;\n- `SHA-256`;\n- `SHA3-256`.\n\nThe decryption process uses the obfuscated string and pass it to the `decrypt()` method of the `Feistel.FPECipher`.\n\n```scala\nimport com.cyrildever.feistel.Feistel\nimport com.cyrildever.feistel.common.utils.hash.Engine._\n\nval source = \"my-source-data\"\n\n// Encrypt\nval cipher = Feistel.FPECipher(SHA_256, \"some-32-byte-long-key-to-be-safe\", 10)\nval obfuscated = cipher.encrypt(source)\n\n// Decrypt\nval deciphered = cipher.decrypt(obfuscated)\n\nassert(deciphered == source)\n\n// For preserving numbers\nval sourceNumber = 123456789\nval obfuscatedNumber = cipher.encryptNumber(sourceNumber)\nval decipheredNumber = cipher.decryptNumber(obfuscatedNumber)\nassert(decipheredNumber == sourceNumber)\n```\n\n_NB: You'd also need provide the expected [BouncyCastle JAR file](./bcprov-jdk15to18-1.80.jar)._\n\n\n### Other implementations\n\nFor those interested, I also made two other implementations of this cipher in [Typescript](https://github.com/cyrildever/feistel-cipher), in [Go](https://github.com/cyrildever/feistel) and in [Python](https://github.com/cyrildever/feistel-py).\n\nI also created a special library for redacting classified documents using this FPE cipher. Feel free to [contact me](mailto:cdever@pep-s.com) about it.\n\n\n### White papers\n\nI wrote two white papers to make it a fully FPE scheme that you can find in the above-mentioned repositories.\n\n\n### License\n\nThis module is distributed under a MIT license. \\\nSee the [LICENSE](LICENSE) file.\n\n\n\u003chr /\u003e\n\u0026copy; 2021-2025 Cyril Dever. All rights reserved.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcyrildever%2Ffeistel-jar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcyrildever%2Ffeistel-jar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcyrildever%2Ffeistel-jar/lists"}