{"id":29533225,"url":"https://github.com/vault12/capacitor-shamir","last_synced_at":"2025-07-17T00:04:18.173Z","repository":{"id":302702828,"uuid":"974514088","full_name":"vault12/capacitor-shamir","owner":"vault12","description":"Native Shamir Secret Sharing. Securely split \u0026 restore secrets on iOS, Android, and Web with a single Capacitor plugin.","archived":false,"fork":false,"pushed_at":"2025-07-03T19:35:51.000Z","size":587,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-07-03T19:54:12.159Z","etag":null,"topics":["android","capacitor","capacitor-android","capacitor-ios","capacitor-plugin","ionic-framework","ios","secret-management","shamir","shamir-algorithm","shamir-secret-sharing"],"latest_commit_sha":null,"homepage":"","language":"Java","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/vault12.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","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,"zenodo":null}},"created_at":"2025-04-28T22:37:05.000Z","updated_at":"2025-07-03T19:42:02.000Z","dependencies_parsed_at":"2025-07-03T19:54:16.750Z","dependency_job_id":"569b459e-4f48-4916-8dd4-fb999ff9cc87","html_url":"https://github.com/vault12/capacitor-shamir","commit_stats":null,"previous_names":["vault12/capacitor-shamir"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/vault12/capacitor-shamir","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vault12%2Fcapacitor-shamir","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vault12%2Fcapacitor-shamir/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vault12%2Fcapacitor-shamir/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vault12%2Fcapacitor-shamir/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vault12","download_url":"https://codeload.github.com/vault12/capacitor-shamir/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vault12%2Fcapacitor-shamir/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265553021,"owners_count":23787013,"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":["android","capacitor","capacitor-android","capacitor-ios","capacitor-plugin","ionic-framework","ios","secret-management","shamir","shamir-algorithm","shamir-secret-sharing"],"created_at":"2025-07-17T00:01:40.873Z","updated_at":"2025-07-17T00:04:18.167Z","avatar_url":"https://github.com/vault12.png","language":"Java","funding_links":[],"categories":["Other plugins"],"sub_categories":["Specialized Hardware"],"readme":"# capacitor-shamir\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/user-attachments/assets/eed959d4-66fc-485d-9467-8fb1c57b9357\"\n    alt=\"Capacitor Shamir\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eA powerful Capacitor plugin for secure secret sharing using Shamir's Secret Sharing algorithm\u003c/strong\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/vault12/capacitor-shamir/releases\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/capacitor-shamir\" alt=\"NPM Release\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/vault12/capacitor-shamir/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/vault12/capacitor-shamir/actions/workflows/ci.yml/badge.svg\" alt=\"Build Status\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/vault12/capacitor-shamir/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/vault12/capacitor-shamir/blob/badges/badges/coverage-total.svg\" alt=\"Coverage\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://opensource.org/licenses/MIT\"\u003e\u003cimg src=\"https://img.shields.io/badge/License-MIT%20OR%20Apache--2.0-blue.svg\" alt=\"Dual License: MIT OR Apache-2.0\" /\u003e\u003c/a\u003e\n  \u003ca href=\"http://makeapullrequest.com\"\u003e\u003cimg src=\"https://img.shields.io/badge/PRs-welcome-brightgreen.svg\" alt=\"PRs Welcome\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.npmjs.com/package/capacitor-shamir\"\u003e\u003cimg src=\"https://img.shields.io/npm/dm/capacitor-shamir\" alt=\"Downloads\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n## 🎯 What is Shamir's Secret Sharing?\n\n[Shamir's Secret Sharing](https://en.wikipedia.org/wiki/Shamir%27s_secret_sharing) is a cryptographic algorithm that divides a secret into multiple parts (shards), where a minimum threshold of shards is required to reconstruct the original secret. This ensures that:\n\n- **No single shard** reveals any information about the secret\n- **Any threshold number** of shards can reconstruct the secret\n- **Security through distribution** - store shards separately for maximum security\n\n### Security\n\nShamir's Secret Sharing provides **information-theoretic security**, which means the algorithm is mathematically proven to be unbreakable regardless of computational power. Key security advantages:\n\n- **Quantum Resistance**: Security relies on mathematical impossibility rather than computational complexity, remaining secure against quantum computers\n- **No Key Management**: There is no single master key to rotate or protect; instead, security hinges on distributing and safeguarding the individual shares\n- **Mathematical Foundation**: Based on [polynomial interpolation over finite fields](#finite-field-implementation), where reconstructing the secret without sufficient shards is mathematically impossible, not just computationally difficult\n\n## ✨ Features\n\n- **Secure Secret Splitting**: Split sensitive data into encrypted shards using Shamir's Secret Sharing\n- **Cross-Platform**: Native support for iOS, Android, and Web\n- **Flexible Storage**: Memory-based and filesystem-based operations\n- **Progress Tracking**: Real-time progress callbacks for all operations\n- **Performance Optimized**: Efficient handling of large files and data\n- **Recovery Options**: Restore complete secrets or individual shards\n\n## 🏆 Real-World Usage\n\nThis plugin is actively used in production by **[Vault12 Guard](https://vault12.com)** - a mobile app that provides secure, decentralized backup and recovery for crypto seed phrases and other sensitive data using Shamir's Secret Sharing.\n\n## 📦 Installation\n\n```bash\nnpm install capacitor-shamir\nnpx cap sync\n```\n\n### Platform Quirks\n\n#### Requirements\nThis plugin requires **Capacitor 7 or higher**.\n\n#### Web\nThe web implementation uses [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) for file operations and includes all necessary polyfills.\n\n## 🚀 Quick Start\n\n```typescript\nimport { Shamir } from 'capacitor-shamir';\n\n// Split a secret into 5 shards, requiring 3 to reconstruct\nconst secret = btoa(\"My secret data\");\nawait Shamir.generateShards({\n  totalShards: 5,\n  threshold: 3,\n  inputDataBase64: secret\n}, (data, error) =\u003e {\n  if (error) {\n    console.error('Error:', error);\n    return;\n  }\n\n  if (data?.shardsBase64) {\n    console.log('Secret split into shards:', data.shardsBase64);\n  } else {\n    console.log('Progress:', data?.progress + '%');\n  }\n});\n```\n\n## API Reference\n\n### Overview\n\nThis plugin provides both **memory-based** and **file-based** API methods for:\n- **Splitting** secret data into cryptographic shards\n- **Restoring** secret data from cryptographic shards\n- **Recovering** individual N-th shard from a set of cryptographic shards\n\n### Key Implementation Details\n\n#### Progress Reporting\n\nAll methods use callback-based progress reporting to provide real-time updates during operations.\n\n#### Job Completion\n\nA job is complete when the callback's `data` object contains a result property with a truthy value:\n- `dataBase64` - for restored secret data\n- `shardsBase64` - for generated shards in memory\n- `shardsPath` / `shardsPaths` - for file-based operations\n- `dstPath` - for file restoration\n\n\u003e [!IMPORTANT]\n\u003e Use `progress` only for UI updates, not to detect completion. A job is done when `!!dataBase64` (or other result property), not when `progress === 100`.\n\n#### Data Format\n\nSince Capacitor doesn't support blob data transfer, all data exchange uses Base64-encoded strings.\n\n## Methods\n\n| Category | Methods | Description |\n|----------|---------|-------------|\n| **Memory Operations** | `generateShards`, `restoreFromShards`, `restoreShard` | Work with Base64 data in memory |\n| **File Operations** | `generateFileShards`, `restoreFromFileShards`, `restoreFileShard` | Direct file-to-file operations |\n| **Hybrid Operations** | `generateShardsToFiles`, `restoreFromFileShardsToData` | Convert between memory and file formats |\n\n\u003cdocgen-index\u003e\n\n* [`generateShards(...)`](#generateshards)\n* [`restoreFromShards(...)`](#restorefromshards)\n* [`restoreShard(...)`](#restoreshard)\n* [`generateFileShards(...)`](#generatefileshards)\n* [`generateShardsToFiles(...)`](#generateshardstofiles)\n* [`restoreFromFileShards(...)`](#restorefromfileshards)\n* [`restoreFromFileShardsToData(...)`](#restorefromfileshardstodata)\n* [`restoreFileShard(...)`](#restorefileshard)\n* [Interfaces](#interfaces)\n\n\u003c/docgen-index\u003e\n\n\u003cdocgen-api\u003e\n\u003c!--Update the source file JSDoc comments and rerun docgen to update the docs below--\u003e\n\n### generateShards(...)\n\n```typescript\ngenerateShards(options: { totalShards: number; threshold: number; inputDataBase64: string; }, callback: (data?: { progress: number; shardsBase64?: string[] | undefined; } | undefined, error?: Error | undefined) =\u003e void) =\u003e Promise\u003cvoid\u003e\n```\n\nSplits secret data (Base64) into encrypted shards in memory.\n\n| Param          | Type                                                                                                                | Description                                                                           |\n| -------------- | ------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |\n| **`options`**  | \u003ccode\u003e{ totalShards: number; threshold: number; inputDataBase64: string; }\u003c/code\u003e                                   | totalShards (≤255), threshold (≥2, ≤255), and inputDataBase64 (Base64-encoded secret) |\n| **`callback`** | \u003ccode\u003e(data?: { progress: number; shardsBase64?: string[]; }, error?: \u003ca href=\"#error\"\u003eError\u003c/a\u003e) =\u0026gt; void\u003c/code\u003e | Reports progress and returns shards as Base64 strings                                 |\n\n--------------------\n\n\n### restoreFromShards(...)\n\n```typescript\nrestoreFromShards(options: { inputShardsBase64: string[]; }, callback: (data?: { progress: number; dataBase64?: string | undefined; } | undefined, error?: Error | undefined) =\u003e void) =\u003e Promise\u003cvoid\u003e\n```\n\nRestores secret data from encrypted shards (all in memory, Base64).\n\n| Param          | Type                                                                                                            | Description                                            |\n| -------------- | --------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ |\n| **`options`**  | \u003ccode\u003e{ inputShardsBase64: string[]; }\u003c/code\u003e                                                                   | inputShardsBase64: array of Base64-encoded shards      |\n| **`callback`** | \u003ccode\u003e(data?: { progress: number; dataBase64?: string; }, error?: \u003ca href=\"#error\"\u003eError\u003c/a\u003e) =\u0026gt; void\u003c/code\u003e | Reports progress and returns restored secret as Base64 |\n\n--------------------\n\n\n### restoreShard(...)\n\n```typescript\nrestoreShard(options: { shardIndex: number; inputShardsBase64: string[]; }, callback: (data?: { progress: number; dataBase64?: string | undefined; } | undefined, error?: Error | undefined) =\u003e void) =\u003e Promise\u003cvoid\u003e\n```\n\nRestores a specific shard from a set of encrypted shards (all in memory, Base64).\n\n| Param          | Type                                                                                                            | Description                                                |\n| -------------- | --------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- |\n| **`options`**  | \u003ccode\u003e{ shardIndex: number; inputShardsBase64: string[]; }\u003c/code\u003e                                               | shardIndex (\u0026gt;0, ≤255) and inputShardsBase64             |\n| **`callback`** | \u003ccode\u003e(data?: { progress: number; dataBase64?: string; }, error?: \u003ca href=\"#error\"\u003eError\u003c/a\u003e) =\u0026gt; void\u003c/code\u003e | Reports progress and returns the requested shard as Base64 |\n\n--------------------\n\n\n### generateFileShards(...)\n\n```typescript\ngenerateFileShards(options: { totalShards: number; threshold: number; srcPath: string; dstPathRoot: string; }, callback: (data?: { progress: number; shardsPaths?: string[] | undefined; } | undefined, error?: Error | undefined) =\u003e void) =\u003e Promise\u003cvoid\u003e\n```\n\nSplits a file into encrypted shard files.\n\n| Param          | Type                                                                                                               | Description                                                                                    |\n| -------------- | ------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------- |\n| **`options`**  | \u003ccode\u003e{ totalShards: number; threshold: number; srcPath: string; dstPathRoot: string; }\u003c/code\u003e                     | totalShards (≤255), threshold (≥2, ≤255), srcPath (input file), dstPathRoot (output directory) |\n| **`callback`** | \u003ccode\u003e(data?: { progress: number; shardsPaths?: string[]; }, error?: \u003ca href=\"#error\"\u003eError\u003c/a\u003e) =\u0026gt; void\u003c/code\u003e | Reports progress and returns paths to shard files                                              |\n\n--------------------\n\n\n### generateShardsToFiles(...)\n\n```typescript\ngenerateShardsToFiles(options: { totalShards: number; threshold: number; inputDataBase64: string; dstPathRoot: string; }, callback: (data?: { progress: number; shardsPaths?: string[] | undefined; } | undefined, error?: Error | undefined) =\u003e void) =\u003e Promise\u003cvoid\u003e\n```\n\nSplits secret data (Base64) into encrypted shard files.\n\n| Param          | Type                                                                                                               | Description                                                                               |\n| -------------- | ------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------- |\n| **`options`**  | \u003ccode\u003e{ totalShards: number; threshold: number; inputDataBase64: string; dstPathRoot: string; }\u003c/code\u003e             | totalShards (≤255), threshold (≥2, ≤255), inputDataBase64, dstPathRoot (output directory) |\n| **`callback`** | \u003ccode\u003e(data?: { progress: number; shardsPaths?: string[]; }, error?: \u003ca href=\"#error\"\u003eError\u003c/a\u003e) =\u0026gt; void\u003c/code\u003e | Reports progress and returns paths to shard files                                         |\n\n--------------------\n\n\n### restoreFromFileShards(...)\n\n```typescript\nrestoreFromFileShards(options: { shardsPaths: string[]; dstPath: string; }, callback: (data?: { progress: number; dstPath?: string | undefined; } | undefined, error?: Error | undefined) =\u003e void) =\u003e Promise\u003cvoid\u003e\n```\n\nRestores a file from encrypted shard files.\n\n| Param          | Type                                                                                                         | Description                                       |\n| -------------- | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------- |\n| **`options`**  | \u003ccode\u003e{ shardsPaths: string[]; dstPath: string; }\u003c/code\u003e                                                     | shardsPaths (input files), dstPath (output file)  |\n| **`callback`** | \u003ccode\u003e(data?: { progress: number; dstPath?: string; }, error?: \u003ca href=\"#error\"\u003eError\u003c/a\u003e) =\u0026gt; void\u003c/code\u003e | Reports progress and returns the output file path |\n\n--------------------\n\n\n### restoreFromFileShardsToData(...)\n\n```typescript\nrestoreFromFileShardsToData(options: { shardsPaths: string[]; }, callback: (data?: { progress: number; dataBase64?: string | undefined; } | undefined, error?: Error | undefined) =\u003e void) =\u003e Promise\u003cvoid\u003e\n```\n\nRestores secret data (Base64) from encrypted shard files.\n\n| Param          | Type                                                                                                            | Description                                            |\n| -------------- | --------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ |\n| **`options`**  | \u003ccode\u003e{ shardsPaths: string[]; }\u003c/code\u003e                                                                         | shardsPaths (input files)                              |\n| **`callback`** | \u003ccode\u003e(data?: { progress: number; dataBase64?: string; }, error?: \u003ca href=\"#error\"\u003eError\u003c/a\u003e) =\u0026gt; void\u003c/code\u003e | Reports progress and returns restored secret as Base64 |\n\n--------------------\n\n\n### restoreFileShard(...)\n\n```typescript\nrestoreFileShard(options: { shardIndex: number; shardsPaths: string[]; dstPathRoot: string; }, callback: (data?: { progress: number; shardPath?: string | undefined; } | undefined, error?: Error | undefined) =\u003e void) =\u003e Promise\u003cvoid\u003e\n```\n\nRestores a specific shard file from a set of encrypted shard files.\n\n| Param          | Type                                                                                                           | Description                                                                         |\n| -------------- | -------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |\n| **`options`**  | \u003ccode\u003e{ shardIndex: number; shardsPaths: string[]; dstPathRoot: string; }\u003c/code\u003e                               | shardIndex (\u0026gt;0, ≤255), shardsPaths (input files), dstPathRoot (output directory) |\n| **`callback`** | \u003ccode\u003e(data?: { progress: number; shardPath?: string; }, error?: \u003ca href=\"#error\"\u003eError\u003c/a\u003e) =\u0026gt; void\u003c/code\u003e | Reports progress and returns the path to the restored shard file                    |\n\n--------------------\n\n\n### Interfaces\n\n\n#### Error\n\n| Prop          | Type                |\n| ------------- | ------------------- |\n| **`name`**    | \u003ccode\u003estring\u003c/code\u003e |\n| **`message`** | \u003ccode\u003estring\u003c/code\u003e |\n| **`stack`**   | \u003ccode\u003estring\u003c/code\u003e |\n\n\u003c/docgen-api\u003e\n\n## License\n\nThis project is dual-licensed under **MIT OR Apache-2.0**. You may choose to use this project under the terms of either license.\n\nThis dual licensing approach is necessary because the web implementation includes code derived from [simbo1905/shamir](https://github.com/simbo1905/shamir), which is licensed under the Apache License 2.0.\n\nSee the [LICENSE](LICENSE) file for the full legal text.\n\n## 🛠️ Troubleshooting\n\n### Common Issues\n\n**Large File Performance**\n- For files \u003e 10MB, consider using file-based operations instead of memory-based\n- Monitor progress callbacks to provide user feedback during long operations\n\n**Base64 Encoding**\n- Remember to encode/decode data properly when working with binary content\n\n**Platform Differences**\n- File paths vary between platforms - use absolute paths when possible\n- iOS sandbox restrictions may limit file access locations\n\n## 🧪 Testing\n\n```bash\n# Run unit tests\nnpm run test\n\n# Run platform-specific test cases\nnpm run verify:ios\nnpm run verify:android\n```\n\n## 📱 Platform Support\n\n| Platform | Version | Status |\n|----------|---------|--------|\n| **iOS** | 14.0+ | ✅ Fully supported |\n| **Android** | API 23+ | ✅ Fully supported |\n| **Web** | Modern browsers | ✅ Fully supported |\n\n## 🤝 Contributing\n\nWe welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.\n\n### Development Setup\n\n```bash\n# Clone the repository\ngit clone https://github.com/vault12/capacitor-shamir.git\ncd capacitor-shamir\n\n# Install dependencies\nnpm install\n\n# Build the plugin\nnpm run build\n\n# Run tests\nnpm test\n```\n\n## 📝 Changelog\n\nSee [Releases](https://github.com/vault12/capacitor-shamir/releases) for detailed changelog.\n\n## 🙏 Acknowledgments\n\n\u003ca id=\"finite-field-implementation\"\u003e\u003c/a\u003e\n\n- Web implementation includes code derived from [simbo1905/shamir](https://github.com/simbo1905/shamir) under the Apache License 2.0\n- Finite field mathematics implementation based on [*The Laws of Cryptography: The Finite Field GF(2\u003csup\u003e8\u003c/sup\u003e)* by Neal R. Wagner](https://web.archive.org/web/20180131040703/http://www.cs.utsa.edu/~wagner/laws/FFM.html)\n- Built for [Capacitor](https://capacitorjs.com/) framework\n- Implements [Shamir's Secret Sharing](https://en.wikipedia.org/wiki/Shamir%27s_secret_sharing) algorithm\n\n## 📞 Support\n\n- 🐛 [Issue Tracker](https://github.com/vault12/capacitor-shamir/issues)\n\n---\n\n\u003cp align=\"center\"\u003e\n  Made with ❤️ by the \u003ca href=\"https://github.com/vault12\"\u003eVault12 Team\u003c/a\u003e\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvault12%2Fcapacitor-shamir","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvault12%2Fcapacitor-shamir","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvault12%2Fcapacitor-shamir/lists"}