{"id":50487087,"url":"https://github.com/systemslibrarian/meow-decoder","last_synced_at":"2026-06-01T23:03:48.061Z","repository":{"id":334259223,"uuid":"1140721911","full_name":"systemslibrarian/meow-decoder","owner":"systemslibrarian","description":"Secure Optical Air-Gap File Transfer via QR-Code GIFs Hiss secrets into yarn balls 😼 — cat-meme QR GIFs built for camera loss (fountain codes) and fail-closed crypto.","archived":false,"fork":false,"pushed_at":"2026-05-05T11:48:35.000Z","size":174428,"stargazers_count":2,"open_issues_count":14,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-05T12:42:47.730Z","etag":null,"topics":["aead","aes-gcm","air-gap","argon2id","forward-secrecy","fountain-codes","hkdf","ml-kem","plausible-deniability","post-quantum-cryptography","steganography","x25519"],"latest_commit_sha":null,"homepage":"https://www.meowdecoder.com/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/systemslibrarian.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":"SUPPORT.md","governance":null,"roadmap":"docs/ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-23T17:06:40.000Z","updated_at":"2026-05-05T11:48:39.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/systemslibrarian/meow-decoder","commit_stats":null,"previous_names":["systemslibrarian/meow-decoder"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/systemslibrarian/meow-decoder","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/systemslibrarian%2Fmeow-decoder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/systemslibrarian%2Fmeow-decoder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/systemslibrarian%2Fmeow-decoder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/systemslibrarian%2Fmeow-decoder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/systemslibrarian","download_url":"https://codeload.github.com/systemslibrarian/meow-decoder/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/systemslibrarian%2Fmeow-decoder/sbom","scorecard":{"id":1243117,"data":{"date":"2026-02-08T22:31:53Z","repo":{"name":"github.com/systemslibrarian/meow-decoder","commit":"a3e100f87fa908f918731abd095bc60ea35ca59a"},"scorecard":{"version":"v5.1.1","commit":"cd152cb6742c5b8f2f3d2b5193b41d9c50905198"},"score":7.2,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/17 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"project was created in last 90 days. please review its contents carefully","details":["Warn: Repository was created in last 90 days."],"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#dangerous-workflow"}},{"name":"Dependency-Update-Tool","score":10,"reason":"update tool detected","details":["Info: detected update tool: Dependabot: .github/dependabot.yml:1"],"documentation":{"short":"Determines if the project uses a dependency update tool.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#dependency-update-tool"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#binary-artifacts"}},{"name":"Security-Policy","score":10,"reason":"security policy file detected","details":["Info: security policy file detected: SECURITY.md:1","Info: Found linked content: SECURITY.md:1","Info: Found disclosure, vulnerability, and/or timelines in security policy: SECURITY.md:1","Info: Found text in security policy: SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#security-policy"}},{"name":"Token-Permissions","score":9,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: jobLevel 'actions' permission set to 'write': .github/workflows/cleanup.yml:28","Info: jobLevel 'contents' permission set to 'read': .github/workflows/formal-verification.yml:40","Info: jobLevel 'contents' permission set to 'read': .github/workflows/release.yml:25","Info: jobLevel 'actions' permission set to 'read': .github/workflows/release.yml:67","Info: jobLevel 'contents' permission set to 'read': .github/workflows/scorecard.yml:30","Info: jobLevel 'actions' permission set to 'read': .github/workflows/scorecard.yml:32","Info: topLevel 'contents' permission set to 'read': .github/workflows/ci.yml:26","Info: found token with 'none' permissions: .github/workflows/cleanup.yml:1","Info: topLevel 'actions' permission set to 'read': .github/workflows/codeql.yml:12","Info: topLevel 'contents' permission set to 'read': .github/workflows/codeql.yml:13","Warn: topLevel 'security-events' permission set to 'write': .github/workflows/codeql.yml:14","Info: topLevel 'contents' permission set to 'read': .github/workflows/formal-verification.yml:34","Info: topLevel 'contents' permission set to 'read': .github/workflows/fuzz.yml:15","Info: topLevel permissions set to 'read-all': .github/workflows/release.yml:18","Info: topLevel 'contents' permission set to 'read': .github/workflows/rust-crypto.yml:21","Info: topLevel 'contents' permission set to 'read': .github/workflows/rust-test-coverage.yml:11","Info: topLevel permissions set to 'read-all': .github/workflows/scorecard.yml:18","Info: topLevel 'contents' permission set to 'read': .github/workflows/security-ci.yml:10"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":10,"reason":"all dependencies are pinned","details":["Info:  54 out of  54 GitHub-owned GitHubAction dependencies pinned","Info:  21 out of  21 third-party GitHubAction dependencies pinned","Info:   1 out of   1 containerImage dependencies pinned","Info:  43 out of  43 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":2,"reason":"badge detected: InProgress","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#cii-best-practices"}},{"name":"SAST","score":8,"reason":"SAST tool detected but not run on all commits","details":["Info: SAST configuration detected: CodeQL","Warn: 18 commits out of 26 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#sast"}},{"name":"Fuzzing","score":10,"reason":"project is fuzzed","details":["Info: PythonAtherisFuzzer integration found: fuzz/fuzz_crypto.py:13","Info: PythonAtherisFuzzer integration found: fuzz/fuzz_fountain.py:10","Info: PythonAtherisFuzzer integration found: fuzz/fuzz_manifest.py:10"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#fuzzing"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/rust-crypto.yml:192"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#packaging"}},{"name":"Vulnerabilities","score":5,"reason":"5 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-h37v-hp6w-2pp8","Warn: Project is vulnerable to: RUSTSEC-2024-0436","Warn: Project is vulnerable to: RUSTSEC-2023-0071","Warn: Project is vulnerable to: RUSTSEC-2026-0009 / GHSA-r6v5-fh4h-64xc","Warn: Project is vulnerable to: GHSA-79v4-65xg-pq4g"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#vulnerabilities"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#signed-releases"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#license"}},{"name":"Contributors","score":0,"reason":"project has 0 contributing companies or organizations -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project has a set of contributors from multiple organizations (e.g., companies).","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#contributors"}},{"name":"CI-Tests","score":10,"reason":"15 out of 15 merged PRs checked by a CI test -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project runs tests before pull requests are merged.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#ci-tests"}}]},"last_synced_at":"2026-02-08T22:32:40.124Z","repository_id":334259223,"created_at":"2026-02-08T22:32:40.124Z","updated_at":"2026-02-08T22:32:40.124Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33797129,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-01T02:00:06.963Z","response_time":115,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["aead","aes-gcm","air-gap","argon2id","forward-secrecy","fountain-codes","hkdf","ml-kem","plausible-deniability","post-quantum-cryptography","steganography","x25519"],"created_at":"2026-06-01T23:03:46.964Z","updated_at":"2026-06-01T23:03:48.051Z","avatar_url":"https://github.com/systemslibrarian.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🐱 Meow Decoder\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/meow-decoder-logo.png\" alt=\"Meow Decoder Logo\" width=\"600\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eMove files offline — show, scan, recover\u003c/strong\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cem\u003eMeow Decoder moves files between computers without a network. The sender shows an encrypted transfer on screen, the receiver phone captures it with a camera, and the file is recovered on the other side. No Wi-Fi, no Bluetooth, no cloud.\u003c/em\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eWhy use it?\u003c/strong\u003e When two machines shouldn't share a network — air-gapped systems, sensitive transfers, hostile environments — Meow Decoder turns any screen into a one-way data path. Files are encrypted before they leave the sender (AES-256-GCM, with optional forward secrecy and post-quantum hybrid), so the phone in the middle never sees the plaintext. Strong by default; advanced and experimental modes available when you need them.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/systemslibrarian/meow-decoder/actions/workflows/security-ci.yml\"\u003e\n    \u003cimg src=\"https://github.com/systemslibrarian/meow-decoder/actions/workflows/security-ci.yml/badge.svg\" alt=\"Security CI\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/systemslibrarian/meow-decoder/actions/workflows/codeql.yml\"\u003e\n    \u003cimg src=\"https://github.com/systemslibrarian/meow-decoder/actions/workflows/codeql.yml/badge.svg\" alt=\"CodeQL\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/systemslibrarian/meow-decoder/actions/workflows/formal-verification.yml\"\u003e\n    \u003cimg src=\"https://github.com/systemslibrarian/meow-decoder/actions/workflows/formal-verification.yml/badge.svg\" alt=\"Formal Verification\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/systemslibrarian/meow-decoder/actions/workflows/fuzz.yml\"\u003e\n    \u003cimg src=\"https://github.com/systemslibrarian/meow-decoder/actions/workflows/fuzz.yml/badge.svg\" alt=\"Fuzzing\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/systemslibrarian/meow-decoder/actions/workflows/rust-security-suite.yml\"\u003e\n    \u003cimg src=\"https://github.com/systemslibrarian/meow-decoder/actions/workflows/rust-security-suite.yml/badge.svg\" alt=\"Rust Crypto Security Suite\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://codecov.io/gh/systemslibrarian/meow-decoder\"\u003e\n    \u003cimg src=\"https://codecov.io/gh/systemslibrarian/meow-decoder/branch/main/graph/badge.svg?token=EBYQIEJETU\" alt=\"Coverage\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://securityscorecards.dev/viewer/?uri=github.com/systemslibrarian/meow-decoder\"\u003e\n    \u003cimg src=\"https://api.securityscorecards.dev/projects/github.com/systemslibrarian/meow-decoder/badge\" alt=\"OpenSSF Scorecard\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://creativecommons.org/licenses/by-nc-sa/4.0/\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/License-CC%20BY--NC--SA%204.0-lightgrey.svg\" alt=\"License: CC BY-NC-SA 4.0\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://www.python.org/downloads/\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/python-3.10+-blue.svg\" alt=\"Python 3.10+\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/systemslibrarian/meow-decoder\"\u003e\u003cimg src=\"https://badgen.net/badge/😺%20cat/approved/orange\" alt=\"😺 Cat Approved\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/systemslibrarian/meow-decoder\"\u003e\u003cimg src=\"https://badgen.net/badge/🐾%20tested/9%20lives/green\" alt=\"🐾 9 Lives\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/systemslibrarian/meow-decoder\"\u003e\u003cimg src=\"https://badgen.net/badge/😼%20security/hiss%20level%209/red\" alt=\"😼 Hiss\"\u003e\u003c/a\u003e\n   \u003ca href=\"https://github.com/systemslibrarian/meow-decoder\"\u003e\u003cimg src=\"https://badgen.net/badge/😿%20bugs/caused%20by%20tail/orange\" alt=\"bugs caused by tail\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"http://www.meowdecoder.com/\"\u003e🌐 \u003cstrong\u003eLive Demo → meowdecoder.com\u003c/strong\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n## ⭐ Start Here — Recommended Path\n\nIf you are new to Meow Decoder, use the standard encrypted transfer flow:\n\n1. **Encode** the file on the sender desktop.\n2. **Show** the transfer on screen.\n3. **Scan** with Meow Capture (mobile) or the browser receiver.\n4. **Export** the capture artifact from the receiver.\n5. **Recover** and decrypt on the receiving desktop.\n\nThat is the path the project is most ready to support end-to-end. See [QUICKSTART.md](QUICKSTART.md) for a five-minute walkthrough.\n\n| Maturity | What belongs here |\n|----------|-------------------|\n| **Recommended** | Standard encrypted offline transfer, guided mobile capture, standard export and desktop recovery |\n| **Advanced** | Redundancy tuning, diagnostics, alternate receiver workflows, hardware-backed security paths (HSM / YubiKey / TPM) |\n| **Experimental** | Schrödinger mode, camouflage and stego presentation layers, deniability and duress-heavy workflows |\n\nRecommended is the path the project optimizes for. Advanced is useful power-user capability. Experimental may still be valuable, but it isn't the default product promise — see [docs/TRUST_CENTER.md](docs/TRUST_CENTER.md) for how to think about each tier.\n\n### Trust and release information\n\n| Question | Where |\n|---|---|\n| What does each maturity tier mean? | [docs/TRUST_CENTER.md](docs/TRUST_CENTER.md) |\n| How is each release artifact signed and distributed? | [docs/RELEASE_MATURITY.md](docs/RELEASE_MATURITY.md) |\n| What hardware paths are validated? | [docs/HARDWARE_TEST_MATRIX.md](docs/HARDWARE_TEST_MATRIX.md) |\n| What would an external auditor need? | [docs/AUDIT_READINESS.md](docs/AUDIT_READINESS.md) |\n| Threat model (what we protect against) | [docs/THREAT_MODEL.md](docs/THREAT_MODEL.md) |\n\n## Who This Is For\n\nMeow Decoder is built for people who need to move files **without using a network** — across an air gap, between isolated machines, or anywhere Wi-Fi, Bluetooth, and cloud sync are off the table.\n\n**Best fit if you want to:**\n- move data between machines that should not share a network\n- run a desktop tool on the sender and the receiver\n- keep encryption applied before the file ever leaves your machine\n- audit the crypto yourself\n\n**Less ideal if you want:**\n- a one-tap consumer app on both ends — the desktop side still expects a developer or operator\n- a vendor-supported enterprise product with an SLA and support contract\n\n**⚖️ Legal Notice:** Meow Decoder is not intended to circumvent law enforcement or legal obligations. Steganography and deniability features are limited and detectable under forensic examination.\n\n**📜 Intended Use:** Designed for legal privacy needs, such as journalist-source protection under First Amendment or equivalent laws. Not for illegal activities. Consult legal experts if uncertain about your jurisdiction.\n\n## 📱 Mobile Companion App — Download Now\n\n[**Meow Capture**](mobile/README.md) — *A secure offline QR capture companion app for air-gapped file transfer.*\n\nPoint your phone at the animated QR code on your screen and let Meow Capture handle the rest — no network, no cloud, no traces.\n\n### 📥 Install on Android (sideload — free)\n\n\u003e **Google Play Store listing coming soon.**\n\n1. On your Android phone, go to **Settings → Apps → Special app access → Install unknown apps** and allow your browser.\n2. Open this link on your phone and tap **Download**:\n\n   **[⬇ Download Meow Capture v3.2.1 APK](https://github.com/systemslibrarian/meow-decoder/raw/main/releases/android/meow-decoder-v3.2.1-release.apk)**\n\n   *Future APKs will move to GitHub Releases / Play Store — see [Trust Center](docs/TRUST_CENTER.md) for the maturity tier.*\n\n3. Open the downloaded `.apk` file and tap **Install**.\n4. Launch **Meow Capture** — grant camera permission when prompted.\n\n### 🍎 iOS — Coming Soon\n\nThe iOS version is under active development. **Apple App Store listing coming soon.**\nIn the meantime, iOS users can [scan QR codes via the web demo](examples/wasm_browser_example.html) in Safari.\n\n### 🏪 App Store Availability\n\n| Platform | Status |\n|----------|--------|\n| Android (sideload) | ✅ Available now — [download APK above](#-install-on-android-sideload--free) |\n| Google Play Store | 🔜 Coming soon |\n| iOS App Store | 🔜 Coming soon |\n\n| Feature | Detail |\n|---------|--------|\n| Scanner | VisionCamera v4 (MLKit / AVFoundation) |\n| Security mode | Strict (wipe on background) or Convenience |\n| Export | Biometric-gated JSON → Downloads, ADB pull, SHA-256 verify |\n| Live coaching | Decode rate, duplicate rate, shake, exposure bias hints |\n| Preflight | Calibration Wizard (5-step camera readiness check) |\n| Diagnostics | Hidden long-press panel — JS lag, heap, thermal, FPS |\n| Import | Scan Request QR from sender screen — no JSON file needed |\n| Multi-device | `meow-decoder merge` CLI combines two-phone captures |\n| Tests | 267 passing, ≥95 % coverage, zero network permissions |\n\n---\n\n## ⏱️ How It Works (60 Seconds)\n\n**The Problem:** You need to move a file between two computers that can't touch the network (air-gapped, hostile network, zero-trust).\n\n**The Solution:** Turn the file into animated QR codes, display on screen, record with any camera, decode on the other side.\n\n```\nSender: secret.pdf → meow-encode → Animated QR GIF\n                                       ↓ (phone camera)\n                                    Video File\n                                       ↓ (transfer)\nReceiver: Video → meow-decode → secret.pdf (recovered)\n```\n\n**That's it.** The phone is just a dumb optical sensor. All crypto happens on trusted computers.\n\n---\n\n## 🎬 Demo\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://raw.githubusercontent.com/systemslibrarian/meow-decoder/main/assets/demo.gif\"\u003e\n    \u003cimg src=\"assets/demo.gif\" alt=\"Meow Decoder demo: Encode → Transmit → Decode\" width=\"260\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\nThis demo shows the **explicit mechanics** of Meow Decoder.\nQR codes are intentionally visible so first-time users can clearly understand what is happening.\n\n### 🔓 Try It Yourself!\n\n**The demo GIF contains a real encrypted message you can decode:**\n\n| Demo File | Description | Download |\n|-----------|-------------|----------|\n| `demo.gif` | Standard QR animation | [Download](https://raw.githubusercontent.com/systemslibrarian/meow-decoder/main/assets/demo.gif) |\n\n**Password:** `JesusIsTheSonOfGod`\n\n```bash\n# Download and decode the demo\ncurl -O https://raw.githubusercontent.com/systemslibrarian/meow-decoder/main/assets/demo.gif\nmeow-decode-gif -i demo.gif -o message.txt -p \"JesusIsTheSonOfGod\"\ncat message.txt\n```\n\n**Hidden message:** John 3:16 (KJV) - *\"For God so loved the world...\"*\n\n---\n\n## 🚀 Quick Start (5 Minutes)\n\n### 1. Install\n\n```bash\npip install meow-decoder\n```\n\nOr from source:\n```bash\ngit clone https://github.com/systemslibrarian/meow-decoder.git\ncd meow-decoder\npip install -e .\n```\n\n### 2. Encode → Transfer → Decode\n\n```bash\n# Sender: Encrypt file into animated QR GIF\nmeow-encode -i secret.pdf -o secret.gif -p \"YourStrongPassword123\"\n\n# Receiver: Decrypt from video recording\nmeow-decode-gif -i captured_video.mp4 -o recovered.pdf -p \"YourStrongPassword123\"\n```\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e📹 Recording \u0026 Transfer Details\u003c/strong\u003e\u003c/summary\u003e\n\n**Display the GIF:**\n```bash\nopen secret.gif      # macOS\nxdg-open secret.gif  # Linux\nstart secret.gif     # Windows\n```\n\n**Record:** Point your phone camera at the screen for 10-15 seconds (GIF loops automatically).\n\n**Transfer:** Move the video to the receiving computer via USB, email, or cloud. The video is encrypted garbage without the password.\n\n**Decode:** Run `meow-decode-gif` as shown above.\n\n\u003c/details\u003e\n\n**Done!** File recovered with integrity verification.\n\n---\n\n## ✨ Key Features\n\n| Feature | Description |\n|---------|-------------|\n| 🔒 **AES-256-GCM** | Military-grade authenticated encryption |\n| 🔑 **Argon2id** | Memory-hard KDF (512 MiB, 20 iterations) |\n| 📱 **Air-Gap Friendly** | Transfer via any camera, no network needed |\n| 🛡️ **Forward Secrecy** | X25519 ephemeral keys (DEFAULT) |\n| 🐈‍⬛ **Schrödinger Mode** | Dual-secret plausible deniability |\n| 🔮 **Post-Quantum** | ML-KEM-768 (default, Signal PQXDH) / ML-KEM-1024 (paranoid) + ML-DSA-65 hybrid |\n| 📊 **Fountain Codes** | Tolerates 33% frame loss in multi-frame QR (Python + JavaScript) |\n| 🔐 **Duress Mode** | Panic password triggers secure wipe |\n| 🖥️ **Hardware Keys** | HSM/PKCS#11, YubiKey PIV/FIDO2, TPM 2.0 PCR binding (`--yubikey`, `--hsm-slot`, `--tpm-seal`) |\n| 📊 **Tamper Report** | Frame-by-frame MAC timeline with cluster detection |\n| 📱 **Mobile Bridge** | React Native QR scanner app with JSON protocol integration |\n| 🌐 **WASM Target** | Browser crypto demo available (`make build-wasm`, see [examples/](examples/)) |\n| 🎨 **Multi-Layer Stego** | Six-channel steganography (LSB+STC, timing, palette, disposal, comment, temporal) for camouflage; not guaranteed against state-grade steganalysis ([audit](docs/STEGO_AUDIT_REPORT.md), [evaluation](docs/STEGO_STRENGTH_EVALUATION.md)) |\n\n---\n\n## 🐈 Camouflage Modes (Optional)\n\nWant the GIF to look innocent instead of obvious QR codes? **Use your own cat photos!**\n\n### Using Custom Carrier Images 🐱\n\nHide your encrypted QR codes inside your own images (cat photos recommended!):\n\n```bash\n# Hide in a single cat photo (cycles through frames)\nmeow-encode -i secret.pdf -o cats.gif --stego-level 3 --carrier my_cat.jpg\n\n# Hide in multiple photos (uses each in sequence)\nmeow-encode -i secret.pdf -o vacation.gif --stego-level 2 --carrier photo1.jpg photo2.jpg photo3.jpg\n\n# Use a glob pattern for all your cat photos\nmeow-encode -i secret.pdf -o cats.gif --stego-level 3 --carrier ~/Pictures/cats/*.jpg\n\n# Maximum stealth mode (paranoid level + obfuscation)\nmeow-encode -i secret.pdf -o innocent.gif --stego-level 4 --carrier *.png\n```\n\n### Stealth Levels\n\n| Level | Name | Description |\n|-------|------|-------------|\n| 0 | Off | Plain QR codes (default) |\n| 1 | Visible | 3-bit LSB, high capacity, visible under analysis |\n| 2 | Subtle | 2-bit LSB, balanced (recommended) |\n| 3 | Hidden | 1-bit LSB, nearly invisible |\n| 4 | Paranoid | 1-bit LSB + noise obfuscation |\n\n\u003c!--\n### 🐱 Cat Mode (Quick Fun Theming)\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/CatMode.png\" alt=\"Cat Mode: Optical Data Transmission demo\" width=\"600\"\u003e\n  \u003cbr\u003e\n  \u003cem\u003eCat Mode: Because sometimes you need to smuggle data… but also look adorable doing it.\u003c/em\u003e\n\u003c/p\u003e\n\n**🌐 Try it in your browser!** The Cat Mode demo runs entirely in WebAssembly — no server needed:\n\n```bash\nmake meow-build\n# Opens http://localhost:8080/examples/wasm_browser_example.html\n```\n\nThe WASM demo includes **8 encryption modes**:\n\n| Mode | Description | Security |\n|------|-------------|----------|\n| 🔐 **Standard** | AES-256-GCM + Argon2id | Full parity with CLI (configurable security levels) |\n| 🔑 **Forward Secrecy** | X25519 ephemeral key exchange | Full parity with CLI |\n| 🔮 **Post-Quantum** | ML-KEM-768 + X25519 PQXDH (default) / ML-KEM-1024 (paranoid) | Quantum resistance |\n| 🐱 **Schrödinger** | Dual-secret plausible deniability | Full parity with CLI |\n| 🖼️ **Stego** | Visual steganography | Browser-limited carrier size |\n| 📹 **Webcam** | Live QR scanner | All payload types supported |\n| 🚨 **Duress** | Panic password wipe | Destroys localStorage keys |\n| 😺 **Cat Mode** | Blinking cat eyes transport for AES-256-GCM + Argon2id ciphertext | Fun camouflage |\n\nSee the [examples/](examples/) directory for full setup instructions.\n\n```bash\n# Quick cat-themed encoding with bundled carrier\nmeow-encode -i secret.pdf -o meow.gif -p \"password\" --cat-mode\n```\n\n⚠️ **WARNING:** Cat Mode is purely cosmetic camouflage for fun. It transports the normal password-based ciphertext and does NOT hide QR codes from steganalysis or forensic detection. Use `--stego-level 4` with custom carriers for serious steganography.\n--\u003e\n\n### 🌿 Green-Region Steganography (`--stego-green`)\n\nRestricts LSB embedding to green-dominant pixels only (e.g., cat eyes, logo waves).\n\n```bash\n# Embed only in green regions of carrier image\nmeow-encode -i secret.pdf -o logo.gif -p \"password\" \\\n    --stego-level 3 --carrier assets/meow-decoder-logo.png --stego-green\n```\n\n⚠️ **IMPORTANT LIMITATIONS:**\n- **Cosmetic only** — reduces visible artifacts but does NOT defeat steganalysis\n- **Reduced capacity** — only ~10-30% of pixels are modifiable\n- **Requires `--carrier`** — must provide carrier image(s) with green regions\n- **Still detectable** — chi-square analysis will find the embedded data\n\n**Best for:** Making embedded QR codes less visually obvious in specific regions.\n**NOT for:** Evading forensic detection or professional steganalysis.\n\n---\n\n## 🛡️ Coercion Resistance Features\n\n### Schrödinger Mode (Dual-Secret Plausible Deniability)\n\nEncodes **two completely separate secrets** into one GIF. Each password reveals a different reality:\n\n```bash\n# Encode two secrets with dual-secret deniability\nmeow-schrodinger-encode \\\n    --real secret_plans.pdf \\\n    --decoy vacation_photos.zip \\\n    --real-password \"ActualSecret123\" \\\n    --decoy-password \"InnocentPassword\" \\\n    -o quantum.gif\n```\n\n| Password Entered | What You Get |\n|------------------|--------------|\n| `ActualSecret123` | Your real secret file |\n| `InnocentPassword` | Innocent decoy content |\n| Wrong password | Decryption fails normally |\n\n\u003e **⚠️ Honest Security Assessment:**\n\u003e\n\u003e Schrödinger mode attempts to encode two independent secrets into one output\n\u003e file. Revealing one password shows a plausible complete payload (decoy or\n\u003e real). Cryptographic deniability is **limited**: while the two encodings are\n\u003e designed to look superficially similar, advanced statistical analysis, timing\n\u003e differences, or comparison of multiple files from the same user may allow a\n\u003e nation-state forensic team to detect the presence of dual encoding or link\n\u003e transfers. This is plausible deniability under casual inspection, **not**\n\u003e perfect cryptographic deniability against unlimited compute and multiple\n\u003e samples. Duress/panic password triggers decoy reveal + key wipe, but\n\u003e memory/swap/forensic recovery may still expose keys if not done perfectly.\n\u003e **Do not rely on this feature alone against a determined state adversary.**\n\n**See also:** [THREAT_MODEL.md](docs/THREAT_MODEL.md) for the full plausible deniability security analysis.\n\n### Duress Mode (Panic Password)\n\n\u003e ✅ **Status: Fully Implemented**\n\nA \"distress signal\" password that **appears to work normally** but secretly:\n1. Shows innocent decoy content (looks like a real decryption)\n2. Silently wipes all encryption keys from memory\n3. Optionally triggers secure deletion of key material\n4. Leaves no trace that a real secret existed\n\n**How to use:**\n```bash\n# During encoding - set up both passwords\nmeow-encode \\\n    -i secret.pdf \\\n    -o secret.gif \\\n    --password \"RealPassword123\" \\\n    --duress-password \"GiveThisToAttacker\"\n\n# During decoding - either password \"works\"\nmeow-decode-gif -i secret.gif -o output.pdf -p \"RealPassword123\"     # Real secret\nmeow-decode-gif -i secret.gif -o output.pdf -p \"GiveThisToAttacker\"  # Decoy + wipe\n```\n\n**If coerced:** Enter the duress password. The attacker sees decoy content, your keys are wiped, and there's no evidence of the real secret.\n\n\n| Feature | Schrödinger Mode | Duress Mode |\n|---------|------------------|-------------|\n| **Purpose** | Limited plausible deniability | Emergency key destruction |\n| **Two secrets?** | ✅ Yes, both recoverable | ❌ Real secret destroyed |\n| **Attacker sees** | Valid decoy content | Valid decoy content |\n| **Keys after** | Both intact | Wiped from memory |\n| **Best for** | Casual inspection cover | Physical coercion |\n\n**⚠️ Warning:** Neither feature protects against determined adversaries with forensic capabilities or physical torture. These are last-resort tools for specific threat models. A nation-state adversary with access to multiple outputs, memory forensics, or the ability to compel disclosure via torture can defeat both mechanisms. Combine with operational security (Tails OS, ephemeral boot media, dead-man switches) for layered defense.\n\n---\n\n## 📱 Phone-Based Transfer Model\n\nMeow Decoder intentionally **does not require a mobile app**.\n\n### Why?\n\n1. **Phones are untrusted** — treat them as dumb optical sensors\n2. **No app = no attack surface** — nothing to exploit on the phone\n3. **Works with any camera** — phone, webcam, DSLR, whatever\n4. **All crypto on trusted machines** — you control the endpoints\n\n### Workflow\n\n1. Display the animated GIF on any screen\n2. Record the looping animation with a phone camera\n3. Transfer the video/photos to a computer\n4. Decode on the computer using the passphrase\n\n---\n\n##  ️ Other Projects\n\nSimilar projects discovered after development began:\n\n| Project | Description | What We Learned |\n|---------|-------------|-----------------|\n| [**TXQR**](https://github.com/divan/txqr) | Transfer via QR - Protocol for animated QR data transfer using fountain codes | Fountain code mechanics for error correction |\n| [**BitFountain**](https://github.com/mguentner/bitfountain) | Experimental data transceiver using QR codes between devices | Camera-to-camera interaction concepts |\n| [**QRExfil**](https://github.com/Shell-Company/QRExfil) | Convert binary files to QR GIFs for air-gapped exfiltration | Demonstrated DLP bypass risks via optical channels |\n| [**QRFileTransfer**](https://github.com/LucaIaco/QRFileTransfer) | Cross-platform offline file transfer using only camera streams | Platform-agnostic optical transfer |\n\n### How Meow Decoder Differs\n\nCompared to these projects, Meow Decoder adds critical security features:\n\n- 🔐 **Authenticated Encryption** — AES-256-GCM with HMAC (not just encoding)\n- 🔮 **Post-Quantum Ready** — ML-KEM-768 (default) / ML-KEM-1024 (paranoid) PQXDH hybrid cryptography\n- 🌊 **Loss-Tolerant** — Fountain codes reconstruct from any ~1.5× k frames\n- 🛡️ **Threat Modeled** — Explicit adversarial analysis ([THREAT_MODEL.md](docs/THREAT_MODEL.md))\n- ⚛️ **Plausible Deniability** — Schrödinger mode with dual-secret encoding\n- 🔑 **Forward Secrecy** — X25519 ephemeral keys protect past messages\n- 🧠 **Memory Hardening** — mlockall, RLIMIT_CORE=0, PR_SET_DUMPABLE, MADV_DONTDUMP\n- 🧹 **Forensic Countermeasures** — Thumbnail/clipboard/history cleanup, tmpfs enforcement, secure delete\n- ⏱️ **Timing Equalization** — Constant wall-clock decode, forced dual-path, CSPRNG jitter\n- 📐 **Size Normalization** — Power-of-4 padding classes prevent file size fingerprinting\n- 💀 **Timed Expiry** — Self-destructing content with configurable TTL\n- 🔒 **Fixed QR Version** — Prevents payload size leakage via QR structure\n- 🎲 **Inter-File Decorrelation** — Randomized encoding parameters prevent profiling\n- 🌐 **Air-Gap Verification** — Network/WiFi/Bluetooth/DNS detection checks\n\n---\n\n# 🔧 Technical Details\n\n*Below the fur: the sections that follow are for developers, security researchers, and contributors who want to understand how the cat's claws actually work.*\n\n---\n\n## 🔍 How It Actually Works (Inside the Cat)\n\n### The Data Pipeline\n\n```\nFile → Compress → Encrypt → Fountain Encode (Luby Transform) → QR Codes → Animated GIF\n\n**Multi-Frame Frame Loss Tolerance:** Payloads \u003e2500 bytes use fountain codes (rateless erasure coding) that allow decoding from ANY ~67% of frames. This solves the \"missed frame\" problem in phone camera capture—autofocus lag, motion blur, and low framerates no longer cause decoding failure. Works in both Python CLI and JavaScript web demo.\n```\n\n| Step | What Happens |\n|------|--------------|\n| **1. Compress** | Your file is compressed with zlib to reduce size |\n| **2. Encrypt** | AES-256-GCM encryption with Argon2id key derivation |\n| **3. Fountain Encode** | Encrypted data split into redundant \"droplets\" using Luby Transform codes |\n| **4. QR Generation** | Each droplet (~500 bytes) becomes a QR code frame |\n| **5. GIF Assembly** | Frame 0 = manifest (metadata), Frames 1+ = data droplets |\n\n### Why Fountain Codes?\n\nFountain codes are \"rateless\" - you can generate infinite droplets, and you only need **~67% of them** to reconstruct the original data. This means:\n\n- 📱 Shaky phone video? No problem\n- 🔄 Missed some frames? Keep going\n- 🌫️ Blurry QR codes? Skip them, decode others\n- ♾️ GIF loops forever, giving multiple chances to capture each frame\n\n### The Optical \"Air Gap\"\n\n```\n┌─────────────┐         ┌─────────────┐         ┌─────────────┐\n│   SENDER    │  light  │   PHONE     │  file   │  RECEIVER   │\n│   SCREEN    │ ──────► │   CAMERA    │ ──────► │   DECODE    │\n│  (GIF plays)│         │ (records)   │         │ (extracts)  │\n└─────────────┘         └─────────────┘         └─────────────┘\n      │                                               │\n      └───────── NO NETWORK CONNECTION ───────────────┘\n```\n\nThe phone is just a \"dumb\" optical sensor carrying photons. It never decrypts anything - all crypto happens on trusted computers at each end.\n\n### Decoding Process\n\n1. **Extract frames** from GIF or video file\n2. **Scan QR codes** from each frame\n3. **Collect droplets** (fountain codes handle missing/corrupted frames)\n4. **Reconstruct** encrypted blob when enough droplets collected\n5. **Decrypt** with your password (Argon2id → AES-256-GCM)\n6. **Decompress** → original file restored\n\n---\n\n## 🔐 What This Protects / Doesn't Protect\n\n### ✅ DOES Protect Against\n\n| Threat | How |\n|--------|-----|\n| **Network eavesdropping** | Data never touches a network |\n| **Man-in-the-middle** | Optical channel, no network routing |\n| **Brute force attacks** | Argon2id (512 MiB, 20 iterations) |\n| **Tampering/modification** | AES-GCM authentication + HMAC |\n| **Future password compromise** | Forward secrecy (X25519 ephemeral keys) |\n| **Coercion (\"give me the password\")** | Schrödinger mode (plausible deniability) |\n| **Dropped/corrupted frames** | Fountain codes (33% loss tolerance) — Python + JS implementation |\n| **Quantum computers (future)** | Post-quantum crypto (ML-KEM-768 with `--pq` / ML-KEM-1024 with `--paranoid`) — opt-in; default is classical X25519 (MEOW3) |\n\n### ❌ Does NOT Protect Against\n\n| Threat | Why |\n|--------|-----|\n| **Shoulder surfing** | Someone watching your screen sees the GIF |\n| **Compromised endpoint** | Malware on sender/receiver defeats everything |\n| **Keyloggers** | Password stolen before encryption |\n| **Physical coercion (torture)** | No crypto defeats rubber-hose cryptanalysis |\n| **Screen recording malware** | Same as shoulder surfing, automated |\n| **State-level adversaries** | No formal audit; use certified tools for classified data |\n\n---\n\n## 🏗️ Architecture — How the Cat Is Built\n\n*Five layers, from Rust primitives at the bottom to cat puns at the top. The deeper you go, the more serious things get.*\n\n```\n┌─────────────────────────────────────────────────────────────────┐\n│                    ENCODING PIPELINE                            │\n├─────────────────────────────────────────────────────────────────┤\n│                                                                 │\n│  File → Compress → Encrypt → Fountain Code → QR Frames → GIF   │\n│          (zlib)   (AES-GCM)  (Luby Transform)  (qrcode)  (PIL)  │\n│                                                                 │\n├─────────────────────────────────────────────────────────────────┤\n│                    DECODING PIPELINE                            │\n├─────────────────────────────────────────────────────────────────┤\n│                                                                 │\n│  GIF/Video → Extract Frames → Read QR → Fountain Decode →      │\n│              (PIL/OpenCV)    (pyzbar)   (Belief Prop)           │\n│                                                                 │\n│           → Decrypt → Decompress → Verify Hash → File          │\n│             (AES-GCM)   (zlib)     (SHA-256)                    │\n│                                                                 │\n└─────────────────────────────────────────────────────────────────┘\n```\n\n**Crypto Stack:**\n- **Encryption:** AES-256-GCM (authenticated)\n- **Key Derivation:** Argon2id (512 MiB memory, 20 iterations)\n- **Forward Secrecy:** X25519 ECDH (DEFAULT ON)\n- **Per-Frame Ratchet:** Signal-inspired symmetric ratchet (MSR v1.2) with header encryption and key commitment\n- **Post-Quantum:** ML-KEM-768 + X25519 PQXDH (default) / ML-KEM-1024 (paranoid), requires receiver PQ public key\n- **Signatures:** ML-DSA-65 + Ed25519 hybrid (manifest auth)\n- **Integrity:** HMAC-SHA256 + per-frame MACs + key commitment tags\n- **Error Correction:** Luby Transform fountain codes\n\nFor full details: [Architecture Documentation](docs/ARCHITECTURE.md)\n\n⚠️ **Manifest signing policy:** Signing is **mandatory** by default. Unsigned manifests are **rejected** (fail-closed).\nTo accept legacy unsigned manifests, set `MEOW_MANIFEST_SIGNING=off` at your own risk. **Always use signing for production/high-risk use.**\n\n---\n\n## 🎯 Security Properties — Nine Lives, All Accounted For\n\n*The playful exterior is backed by real cryptographic guarantees. Here's what the cat is actually made of.*\n\n| Property | Implementation | Status |\n|----------|----------------|--------|\n| Authenticated Encryption | AES-256-GCM | ✅ |\n| Memory-Hard KDF | Argon2id (512 MiB, 20 iter) | ✅ |\n| Tamper Detection | GCM tags + HMAC + frame MACs | ✅ |\n| Forward Secrecy | X25519 ephemeral keys | ✅ Default |\n| Per-Frame Forward Secrecy | Symmetric ratchet (MSR v1.2) | ✅ Optional |\n| Header Encryption | HKDF-XOR masked frame indices | ✅ |\n| Key Commitment | HMAC-SHA256 commitment tags | ✅ |\n| Post-Quantum | ML-KEM-768/1024 + ML-DSA-65 | ✅ Default (768) / Paranoid (1024) |\n| Plausible Deniability | Schrödinger dual-secret | ✅ Optional |\n| Coercion Resistance | Duress passwords | ✅ |\n| Error Recovery | Fountain codes (33% loss OK) | ✅ |\n| Constant-Time Ops | Rust crypto backend | ✅ |\n| Tamper Timeline | Frame-by-frame MAC report | ✅ |\n| Security Tests | 2400+ Python + 800+ Rust tests, CI-enforced (3-gate) | ✅ |\n\n**Full threat model:** [THREAT_MODEL.md](docs/THREAT_MODEL.md)\n\n---\n\n## 🦀 Under the Fur — Rust Crypto Backend (Required)\n\n🔒 All secret-handling cryptography now lives in the Rust core (`crypto_core`). The cat may look playful — but the claws are constant-time.\n\nThe Rust cryptographic backend is **mandatory** for secure operation.\n\n### Why Rust Backend?\n\n| Property | Rust Backend |\n|----------|--------------|\n| Constant-time operations | ✅ Guaranteed (`subtle` crate) |\n| Memory zeroing | ✅ Automatic (`zeroize` crate) |\n| Side-channel resistance | ✅ Audited crates |\n| Performance | ~2x faster |\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e🧠 What the Rust migration actually changes (and what it doesn't)\u003c/strong\u003e\u003c/summary\u003e\n\nThe move to Rust does **not** upgrade AES-256-GCM, X25519, HKDF, Argon2id, or ML-KEM. The math is identical — if AES-256 was 256-bit secure before, it still is.\n\nWhat it improves is the **implementation layer**:\n\n1. **Memory safety** — Rust's `zeroize` crate wipes secrets on drop. Python's garbage collector makes no such guarantee, leaving key material lingering in memory.\n2. **Secret boundary clarity** — Python now handles orchestration only; Rust owns the cryptographic boundary. Cleaner to audit, harder to accidentally leak secrets.\n3. **Constant-time discipline** — The `subtle` crate enforces timing-safe comparisons at the type level, not by convention.\n4. **Auditability** — A compact Rust core is easier for external reviewers to read than crypto scattered across Python modules.\n5. **No silent fallbacks** — If the Rust backend is missing, the system fails closed. CI enforces this. No \"works locally but insecure in production\" surprises.\n\n**Honest summary:** Strong protocol before, strong protocol after. The difference is lower implementation risk, cleaner secret hygiene, and a crypto boundary you can actually audit.\n\nSee [Architecture docs](docs/ARCHITECTURE.md#what-the-rust-migration-does--and-does-not--change) for the full analysis.\n\n\u003c/details\u003e\n\n### Installation\n\n```bash\n# 1. Install Rust (if not already installed)\ncurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\nsource $HOME/.cargo/env\n\n# 2. Install maturin (Python ↔ Rust build tool)\npip install maturin\n\n# 3. Build and install the Rust module\ncd rust_crypto\nmaturin develop --release\ncd ..\n\n# 4. Verify installation\npython -c \"import meow_crypto_rs; print('✅ Rust backend:', meow_crypto_rs.backend_info())\"\n```\n\n### Usage\n\nThe encoder/decoder uses the Rust backend by default once installed.\n**No production Python module imports the `cryptography` library** — all crypto primitives (AES-GCM, HKDF, X25519, Argon2id) route through the Rust backend via `crypto_backend.CryptoBackend()`. This is enforced by an AST-based CI test (`tests/test_crypto_enforcement.py`).\n\n\u003e **Non-production modules** (`spec_v12/`, `experimental/`) are quarantined and excluded from the enforcement scan. See [Architecture docs](docs/ARCHITECTURE.md#production-vs-non-production-code) for details.\n\n**Benchmarks (Typical):**\n*   **Key Derivation (Argon2id):** Rust is ~30% faster\n*   **Encryption (AES-GCM):** Rust is ~2x faster\n*   **Security:** Rust backend uses the `subtle` crate for verified constant-time comparisons.\n\n---\n\n## 🔌 Hardware Security Module Integration\n\n\u003e **Current status:** Primitives are fully implemented in the Rust crypto core. CLI flags (`--yubikey`, `--hsm-slot`, `--tpm-seal`) are available; full end-to-end integration is in final testing.\n\nMeow Decoder supports hardware-backed key storage for high-security environments.\n\n### Supported Hardware\n\n| Device | CLI Flag | Description |\n|--------|----------|-------------|\n| **HSM/PKCS#11** | `--hsm-slot \u003cslot\u003e` | Enterprise HSMs (Thales, Utimaco, SoftHSM) |\n| **YubiKey** | `--yubikey --yubikey-slot \u003c9a\\|9c\\|9d\\|9e\u003e` | PIV slots for key storage |\n| **TPM 2.0** | `--tpm-seal \u003c0-23\u003e` | Platform-bound keys with PCR sealing |\n\n### Example Usage\n\n```bash\n# Encode with YubiKey (PIV slot 9a = authentication)\nmeow-encode -i secret.pdf -o secret.gif --yubikey --yubikey-slot 9a\n\n# Encode with HSM (slot 0)\nmeow-encode -i secret.pdf -o secret.gif --hsm-slot 0\n\n# Encode with TPM (bind to PCR 7 = Secure Boot state)\nmeow-encode -i secret.pdf -o secret.gif --tpm-seal 7\n\n# Decode requires the same hardware present\nmeow-decode-gif -i secret.gif -o recovered.pdf --yubikey --yubikey-slot 9a\n```\n\n### How It Works\n\n1. **Key Generation**: Hardware generates a non-exportable key pair\n2. **Key Wrapping**: AES-256 content key is wrapped by hardware public key\n3. **Wrapped Key in Manifest**: GIF manifest stores the wrapped key blob\n4. **Decryption**: Hardware unwraps the content key; plaintext key never leaves the device\n\n**Security Properties:**\n- Private keys **never leave the hardware** — resistant to memory dumps\n- TPM PCR binding ensures decryption only on specific boot configurations\n- YubiKey requires physical touch for each operation (anti-malware)\n\nSee [crypto_core/README.md](crypto_core/README.md) for Rust API details and advanced configuration.\n\n### WebAuthn Browser Integration (Prototype)\n\n\u003e **Current status:** Prototype implementation available. Basic registration and key derivation working. Full integration with WASM demo in progress.\n\nThe browser demo now supports **WebAuthn/FIDO2 hardware security keys** for hardware-backed encryption:\n\n```javascript\nimport { HardwareKeyManager } from './webauthn-hardware.js';\n\nconst hwManager = new HardwareKeyManager();\n\n// Register a security key (YubiKey, Titan, etc.)\nawait hwManager.register(\"my-username\");\n\n// Derive encryption key with hybrid security:\n// - Password (knowledge factor)\n// - Hardware key signature (possession factor + touch)\nconst key = await hwManager.deriveKey(password, salt, argon2DeriveFunc);\n```\n\n**Security Model:**\n- 🔐 **Key Isolation**: Private keys never leave the hardware authenticator\n- 👆 **Touch Required**: Physical presence verification for each operation\n- 🔑 **Hybrid Derivation**: XORs hardware signature with Argon2id password key\n- 🛡️ **Multi-Factor**: Combines knowledge (password) + possession (key) + presence (touch)\n\n**Supported Keys:**\n- YubiKey 5 Series (FIDO2)\n- Google Titan Security Key\n- Windows Hello (platform authenticator)\n- Any FIDO2/WebAuthn compatible device\n\n**Implementation Files:**\n- [`examples/webauthn-hardware.js`](examples/webauthn-hardware.js) — Core WebAuthn integration\n- [`tests/test_webauthn_integration.html`](tests/test_webauthn_integration.html) — Browser-based unit tests\n\nSee the [examples/](examples/) directory for full setup instructions.\n\n---\n\n## 📱 Mobile Bridge (React Native)\n\n\u003e **Current status:** Production-ready. 267 passing tests, Vision Camera v4 frame processor, full state machine (`IDLE → CAPTURING → COMPLETE`), Zod-validated protocol, chunked JSON export. See [`mobile/README.md`](mobile/README.md) for setup.\n\nThe React Native QR scanner app provides a seamless mobile-to-CLI workflow for capturing animated QR codes.\n\n### Installation\n\n```bash\n# iOS\ncd mobile \u0026\u0026 npx pod-install \u0026\u0026 npx react-native run-ios\n\n# Android\ncd mobile \u0026\u0026 npx react-native run-android\n```\n\n### JSON Protocol\n\nThe mobile app communicates with the CLI via JSON over stdout/stdin or file exchange:\n\n**Capture Request (CLI → App):**\n```json\n{\n  \"action\": \"capture\",\n  \"session_id\": \"uuid-v4\",\n  \"expected_frames\": 45,\n  \"timeout_seconds\": 60\n}\n```\n\n**Frame Data (App → CLI):**\n```json\n{\n  \"session_id\": \"uuid-v4\",\n  \"frames\": [\n    {\"index\": 0, \"data\": \"base64...\", \"timestamp_ms\": 1234567890},\n    {\"index\": 1, \"data\": \"base64...\", \"timestamp_ms\": 1234567950}\n  ],\n  \"capture_complete\": true,\n  \"frames_captured\": 45,\n  \"frames_missed\": 2\n}\n```\n\n**Decode Response (CLI → App):**\n```json\n{\n  \"session_id\": \"uuid-v4\",\n  \"status\": \"success\",\n  \"output_file\": \"/path/to/recovered.pdf\",\n  \"integrity_verified\": true,\n  \"frames_used\": 43\n}\n```\n\n### CLI Integration\n\n```bash\n# Export capture request for mobile app\nmeow-decode-gif --mobile-bridge --output-request capture_request.json\n\n# Import captured frames from mobile\nmeow-decode-gif --mobile-bridge --input-frames captured_frames.json -o recovered.pdf -p \"password\"\n\n# Or use pipe mode (adb/USB bridge)\nadb shell cat /sdcard/meow_frames.json | meow-decode-gif --mobile-bridge -o recovered.pdf -p \"password\"\n```\n\nSee [mobile/ARCHITECTURE.md](mobile/ARCHITECTURE.md) for full protocol specification and app architecture.\n\n---\n\n## 🌐 WASM Browser Demo\n\nRun the crypto core directly in your browser — no server-side processing, fully client-side encryption.\n\n### Web Demo vs CLI Feature Parity\n\n| Feature | CLI (Python) | Web Demo (WASM) | Notes |\n|---------|:------------:|:---------------:|-------|\n| AES-256-GCM | ✅ | ✅ | Identical AEAD |\n| Argon2id KDF | ✅ 512 MiB/20 iter | ✅ Configurable | Web: 64-512 MiB selectable |\n| X25519 Forward Secrecy | ✅ | ✅ | Full parity |\n| ML-KEM-768/1024 Post-Quantum | ✅ | ✅ | Requires `--features wasm-pq` |\n| Schrödinger Mode | ✅ | ✅ | Dual-secret deniability |\n| Fountain Codes | ✅ | ✅ | Full support (Python + JavaScript, 33% frame loss tolerance) |\n| GIF Animation | ✅ | ✅ | Multi-frame QR with fountain codes (loss-tolerant) |\n| Steganography | ✅ Level 0-4 | ⚠️ Level 1-2 | Browser canvas limitations |\n| Hardware Keys | ✅ | 🔬 Prototype | WebAuthn/FIDO2 implementation available ([webauthn-hardware.js](examples/webauthn-hardware.js)) |\n| Webcam Decode | ✅ | ✅ | Real-time camera scanner |\n| Duress Mode | ✅ | ✅ | Panic password wipe |\n| File Upload | ✅ | ✅ | Up to ~2KB per QR |\n\n### Security Level Selection\n\nThe web demo provides **4 security levels** to balance speed vs. brute-force resistance:\n\n| Level | Memory | Iterations | Time | Use Case |\n|-------|--------|------------|------|----------|\n| ⚡ Fast | 64 MiB | 3 | ~1 sec | Quick demos, low-value data |\n| 🔒 Standard | 128 MiB | 8 | ~3 sec | General use |\n| 🛡️ High | 256 MiB | 15 | ~8 sec | Sensitive data |\n| 🔐 Paranoid | 512 MiB | 20 | ~20 sec | **Matches CLI** — life-critical |\n\n⚠️ **For maximum security matching the Python CLI, select \"Paranoid\" mode.** This uses identical Argon2id parameters to the command-line tool.\n\n### Prerequisites\n\n- **Rust** (stable toolchain via [rustup](https://rustup.rs/))\n- **wasm-pack**: `cargo install wasm-pack`\n- **HTTP server**: Python's built-in works, or `npm install -g serve`\n\n### Build the WASM Module\n\n```bash\n# Standard build (X25519 + AES-256-GCM)\nmake build-wasm\n\n# With Post-Quantum ML-KEM-768/1024 support\nwasm-pack build crypto_core --target web --release --features wasm-pq\n```\n\nThis creates `crypto_core/pkg/` with the `.js` and `.wasm` files.\n\n### Run the Demo\n\n```bash\n# One command: build WASM + start server\nmake meow-build\n\n# Then open: http://localhost:8080/examples/wasm_browser_example.html\n```\n\nOr manually:\n\n```bash\n# Build first (if not already done)\nmake build-wasm\n\n# Start HTTP server from project root\npython3 -m http.server 8080\n\n# Open in browser:\n# http://localhost:8080/examples/wasm_browser_example.html\n```\n\n### Codespaces / Dev Container Notes\n\nThis repo includes a `.devcontainer/devcontainer.json` for GitHub Codespaces and VS Code Dev Containers.\n\n**Port Forwarding is Disabled by Default** — This prevents confusing \"Cannot GET /\" errors and popup spam when opening a Codespace. When you're ready to run the WASM demo:\n\n1. Run: `make meow-build`\n2. Open the **Ports** tab (bottom panel)\n3. Forward port 8080 (will auto-detect or right-click → Forward Port)\n4. Click the forwarded URL, then navigate to `/examples/wasm_browser_example.html`\n\n| Scenario | Action |\n|----------|--------|\n| First clone | Run `make meow-build` (~1-2 min to build, then serves) |\n| Resume/reopen | Built files persist — just `make meow-build` starts server |\n| Container rebuild | Re-run `make meow-build` |\n| Rust code changes | Re-run to pick up changes |\n\n\u003e **Why a server?** Browsers block WASM loading from `file://` URLs. The HTTP server provides proper MIME types for `.wasm` files.\n\nSee the [examples/](examples/) directory for full details.\n\n---\n\n## 🧪 Development\n\n```bash\n# Install dev dependencies\npip install -e \".[dev]\"\n\n# Run all tests\npytest tests/\n\n# Run security tests specifically\npytest tests/test_security.py tests/test_adversarial.py\n\n# Run by marker (strict markers enforced)\npytest -m security          # Security-critical tests\npytest -m crypto            # Crypto unit tests\npytest -m \"not slow\"        # Skip slow tests (used in CI Gate 1)\n\n# Run property-based tests (security invariants)\npytest tests/test_property_based.py -v --hypothesis-show-statistics\n\n# Run with coverage\npytest --cov=meow_decoder tests/\n\n# Self-test (verifies backend, roundtrip, fountain codec)\nmeow-encode --self-test\n\n### Property-Based Testing\n\nWe use **Hypothesis** for property-based testing to verify security invariants hold for all possible inputs:\n\n```bash\n# Run with detailed statistics\npytest tests/test_property_based.py -v --hypothesis-show-statistics\n\n# Run exhaustive profile (1000 examples per test)\npytest tests/test_property_based.py --hypothesis-profile=exhaustive\n```\n\nKey invariants tested:\n- **Encrypt/Decrypt Roundtrip**: `decrypt(encrypt(x)) == x` for all x\n- **Tamper Detection**: Any bit flip in ciphertext is detected\n- **Nonce Uniqueness**: Same key never reuses nonce\n\nSee [docs/SECURITY_INVARIANTS.md](docs/SECURITY_INVARIANTS.md) for the complete invariant specification.\n\nCI runs on Python 3.10–3.12 with CodeQL and security scanning.\n\n---\n\n## 🔬 Fuzzing \u0026 Security Testing\n\nWe use AFL++ with Python bindings (atheris) to test robustness against malformed inputs.\n\nFor the full test inventory and coverage tracking, see [tests/TEST_SUITE_README.md](tests/TEST_SUITE_README.md).\n\n### Fuzz Targets\n- **Manifest Parsing**: Tests against malformed binary structures\n- **Crypto Operations**: Tests error handling in key derivation/decryption\n- **Fountain Codes**: Tests droplet parsing logic\n\n### Running Fuzzers\n\n1.  **Install Atheris:**\n    ```bash\n    pip install atheris\n    ```\n\n2.  **Run a Fuzzer:**\n    ```bash\n    # Fuzz manifest parsing logic\n    python3 fuzz/fuzz_manifest.py\n\n    # Fuzz crypto operations\n    python3 fuzz/fuzz_crypto.py\n    ```\n\n**Findings:**\n*   Fuzzing results are not claimed without a recorded run log.\n*   Continuous fuzzing is recommended before major releases.\n\nSee [fuzz/README.md](fuzz/README.md) for details.\n\n---\n\n## 🧪 Formal Verification (TLA+ / ProVerif / Verus)\n\nFormal methods live in [formal/README.md](formal/README.md). Quick commands:\n\n```bash\n# One-command verification\nmake verify\n\n# ProVerif (symbolic protocol analysis)\ncd /workspaces/meow-decoder/formal/proverif\neval $(opam env)\nproverif meow_encode.pv\n\n# TLA+ (state machine model checking)\ncd /workspaces/meow-decoder/formal/tla\njava -jar tla2tools.jar -config MeowEncode.cfg MeowEncode.tla\n\n# Verus (Rust proofs — guard-page memory safety only)\ncd /workspaces/meow-decoder/crypto_core\nverus src/lib.rs\n\n# Tamarin (observational equivalence, optional)\ncd /workspaces/meow-decoder/formal/tamarin\n./run.sh\n```\n\nMore details and expected results:\n- [formal/README.md](formal/README.md)\n- [formal/proverif/README.md](formal/proverif/README.md)\n\n**Scope:** These methods verify protocol and wrapper invariants, not AES‑GCM itself or side‑channel resistance. Tamarin is optional but required for a full local `make verify`; CI skips it unless installed.\n\n\u003e **Verus proof status (honest assessment):**\n\u003e\n\u003e | Proof set | File | Status |\n\u003e |-----------|------|--------|\n\u003e | Guard-page memory safety (GB-001 – GB-008) | `verus_guarded_buffer.rs` | ✅ **Real Verus proofs** — bounds, overflow/underflow, zeroize-on-drop |\n\u003e | AEAD properties (AEAD-001 – AEAD-004) | `verus_proofs.rs` | ⚠️ **Proof stubs only** — structured as doc-comment specifications, not machine-checked Verus proofs. Properties are enforced by Rust's type system (`UniqueNonce`, `AuthenticatedPlaintext`), runtime tests, and the `zeroize` crate — not by Verus. |\n\u003e\n\u003e We do **not** claim formally verified AEAD. The AEAD wrapper's correctness rests on the `aes-gcm` crate's proven security, Rust's ownership system, and comprehensive testing.\n\n### 🎯 Adversary Model\n\n| Adversary | Can Meow Decoder Stop Them? (No Guarantees) |\n|-----------|---------------------------------------------|\n| Script kiddie | ✅ Yes, easily |\n| Skilled hacker (network) | ✅ Yes (no network exposure) |\n| Corporate IT snooping | ✅ Yes (optical bypasses monitoring) |\n| Law enforcement (legal demand) | ❌ Not designed for this  |\n| Intelligence agency | ❌ Not designed for this  |\n| NSA with full resources | ❌ Not designed for this |\n\n** Intended Use:** Designed for legal privacy needs, such as journalist-source protection under First Amendment or equivalent laws. Not for illegal activities. Consult legal experts if uncertain about your jurisdiction.\n\n**Bottom line:** Strong crypto, but endpoints and operational security are YOUR responsibility. No guarantees.\n\n---\n\n## 🔒 Security Review Scope (v1.0)\n\n*Internal security review – not a third-party audit.*\n\nThis release has undergone internal security review (not a third-party audit). Claims are tied to:\n- [docs/THREAT_MODEL.md](docs/THREAT_MODEL.md) (authoritative scope)\n- [docs/PROTOCOL.md](docs/PROTOCOL.md) (byte-level spec)\n- [SECURITY.md](SECURITY.md) (formal methods + limitations)\n\nIf your threat model includes compromised endpoints or hardware side-channels, this tool is out of scope.\n\n---\n\n## 📖 Documentation — The Cat's Library\n\n*From quick demos to deep threat analysis — everything a Cat Herder needs.*\n\n| Document | Description |\n|----------|-------------|\n| [QUICKSTART.md](QUICKSTART.md) | 5-minute phone capture demo |\n| [Usage Guide](docs/USAGE.md) | Detailed usage instructions |\n| [Threat Model](docs/THREAT_MODEL.md) | Security analysis \u0026 limitations |\n| [Architecture](docs/ARCHITECTURE.md) | Technical deep-dive |\n| [Protocol Spec](docs/PROTOCOL.md) | Byte-level protocol specification |\n| [Security Roadmap](docs/ROADMAP.md) | Future security enhancements |\n| [Security Invariants](docs/SECURITY_INVARIANTS.md) | Formal invariant specification |\n| [Spec v1.2 Reference](docs/SPEC_REFERENCE.md) | Protocol reference implementation |\n| [Test Suite](tests/TEST_SUITE_README.md) | Test inventory, coverage \u0026 run instructions |\n| [Mobile Bridge](mobile/ARCHITECTURE.md) | React Native QR bridge architecture |\n| [Security Changes](docs/SECURITY_CHANGES.md) | Security hardening changelog |\n| [Stego Audit Report](docs/STEGO_AUDIT_REPORT.md) | Steganography audit results (43/43 PASS) |\n| [Stego Strength Evaluation](docs/STEGO_STRENGTH_EVALUATION.md) | Comparative steganalysis vs OpenStego, Steghide, StegX |\n| [Security Claims](docs/SECURITY_CLAIMS.md) | Canonical truth file for security claims |\n| [SECURITY.md](SECURITY.md) | Vulnerability reporting \u0026 supply chain security |\n\n---\n\n## 🐾 Contributing — Join the Clowder\n\nWe're always looking for more **Cat Herders**! Especially:\n- 🌿 **Catnip Hunters** — Security researchers (find vulnerabilities, earn your catnip bounty)\n- 🎨 **Grooming Specialists** — UX designers (help make it more accessible)\n- 📱 **Outdoor Cats** — Mobile developers (native app would be great)\n- 🔐 **Apex Predators** — Cryptographers (review our implementation)\n\n**Contributor titles:**\n| Contributions | Title |\n|--------------|-------|\n| First PR merged | 🐱 **Kitten** |\n| 5+ contributions | 🐈 **Tabby** |\n| 20+ or major feature | 🦁 **Maine Coon** |\n| Core maintainer | 🐆 **Apex Predator** |\n\nSee the [Cat Herder's Handbook (CONTRIBUTING.md)](CONTRIBUTING.md) for guidelines.\n\n**Found a vulnerability?** Check the [🌿 Catnip Bounty Program (SECURITY.md)](SECURITY.md).\n**Need help?** Visit the [🐾 Cat Help Desk (SUPPORT.md)](SUPPORT.md).\n**Have a feature idea?** [📦 Add to the Litter Box](https://github.com/systemslibrarian/meow-decoder/issues).\n\n---\n\n##   About the Meow Tone\n\nMeow Decoder blends serious cryptography with a cat-themed personality. This is deliberate.\n\n**Why personality?** Cryptographic tools often intimidate newcomers with walls of jargon. The cat theme lowers the barrier to entry: people who would never read a README about \"AES-256-GCM with Argon2id KDF and PQXDH hybrid key exchange\" will happily read about a cat smuggling secrets through an air gap. The playful surface draws people in; the formal crypto underneath keeps them safe.\n\n**Why not personality everywhere?** Humor in the wrong place is dangerous. A joke in a domain separation label breaks interoperability. A pun in a Rust primitive name confuses auditors. Cat branding stops at the cryptographic boundary — Layers 1–2 of the architecture are dead serious, Layer 3 is professional, and Layers 4–5 are where the cat lives.\n\n**The rule is simple:** the deeper you go, the more serious things get. If you're reading `purr_encrypt()`, you're in the personality layer. If you're reading `aes_gcm_encrypt()`, you're in the trust anchor. Both exist, and neither pretends to be the other.\n\nSee [Architecture Documentation](docs/ARCHITECTURE.md#-architectural-layer-boundaries) for the full 5-layer boundary model.\n\n---\n\n##  📄 License\n\nThis project is licensed under the [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License (CC BY-NC-SA 4.0)](https://creativecommons.org/licenses/by-nc-sa/4.0/).\n\nSee [LICENSE](LICENSE) for the full license text.\n\n---\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eBuilt for air-gapped, hostile, or zero-trust environments.\u003c/strong\u003e\n  \u003cbr\u003e\n  \u003cem\u003e🐱 \"Trust no network. Trust the cat.\" 🐱\u003c/em\u003e\n  \u003cbr\u003e\u003cbr\u003e\n  \u003cstrong\u003e🐾 Community:\u003c/strong\u003e\n  \u003ca href=\"CONTRIBUTING.md\"\u003eCat Herder's Handbook\u003c/a\u003e ·\n  \u003ca href=\"SECURITY.md\"\u003eCatnip Bounty Program\u003c/a\u003e ·\n  \u003ca href=\"SUPPORT.md\"\u003eCat Help Desk\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n\u003cp align=\"center\"\u003e\n  \u003cem\u003eSoli Deo Gloria\u003c/em\u003e\n  \u003cbr\u003e\n  This project is dedicated to God. May He receive all the glory.\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsystemslibrarian%2Fmeow-decoder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsystemslibrarian%2Fmeow-decoder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsystemslibrarian%2Fmeow-decoder/lists"}