npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

capacitor-shamir

v1.0.4

Published

Provides Shamir's Secret Sharing (SSS) functionality for secure splitting and recovering secrets natively on iOS, Android, and Web.

Readme

capacitor-shamir


🎯 What is Shamir's Secret Sharing?

Shamir's 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:

  • No single shard reveals any information about the secret
  • Any threshold number of shards can reconstruct the secret
  • Security through distribution - store shards separately for maximum security

Security

Shamir's Secret Sharing provides information-theoretic security, which means the algorithm is mathematically proven to be unbreakable regardless of computational power. Key security advantages:

  • Quantum Resistance: Security relies on mathematical impossibility rather than computational complexity, remaining secure against quantum computers
  • No Key Management: There is no single master key to rotate or protect; instead, security hinges on distributing and safeguarding the individual shares
  • Mathematical Foundation: Based on polynomial interpolation over finite fields, where reconstructing the secret without sufficient shards is mathematically impossible, not just computationally difficult

✨ Features

  • Secure Secret Splitting: Split sensitive data into encrypted shards using Shamir's Secret Sharing
  • Cross-Platform: Native support for iOS, Android, and Web
  • Flexible Storage: Memory-based and filesystem-based operations
  • Progress Tracking: Real-time progress callbacks for all operations
  • Performance Optimized: Efficient handling of large files and data
  • Recovery Options: Restore complete secrets or individual shards

🏆 Real-World Usage

This plugin is actively used in production by Vault12 Guard - a mobile app that provides secure, decentralized backup and recovery for crypto seed phrases and other sensitive data using Shamir's Secret Sharing.

📦 Installation

npm install capacitor-shamir
npx cap sync

Platform Quirks

Requirements

This plugin requires Capacitor 7 or higher.

Web

The web implementation uses IndexedDB for file operations and includes all necessary polyfills.

🚀 Quick Start

import { Shamir } from 'capacitor-shamir';

// Split a secret into 5 shards, requiring 3 to reconstruct
const secret = btoa("My secret data");
await Shamir.generateShards({
  totalShards: 5,
  threshold: 3,
  inputDataBase64: secret
}, (data, error) => {
  if (error) {
    console.error('Error:', error);
    return;
  }

  if (data?.shardsBase64) {
    console.log('Secret split into shards:', data.shardsBase64);
  } else {
    console.log('Progress:', data?.progress + '%');
  }
});

API Reference

Overview

This plugin provides both memory-based and file-based API methods for:

  • Splitting secret data into cryptographic shards
  • Restoring secret data from cryptographic shards
  • Recovering individual N-th shard from a set of cryptographic shards

Key Implementation Details

Progress Reporting

All methods use callback-based progress reporting to provide real-time updates during operations.

Job Completion

A job is complete when the callback's data object contains a result property with a truthy value:

  • dataBase64 - for restored secret data
  • shardsBase64 - for generated shards in memory
  • shardsPath / shardsPaths - for file-based operations
  • dstPath - for file restoration

[!IMPORTANT] Use progress only for UI updates, not to detect completion. A job is done when !!dataBase64 (or other result property), not when progress === 100.

Data Format

Since Capacitor doesn't support blob data transfer, all data exchange uses Base64-encoded strings.

Methods

| Category | Methods | Description | |----------|---------|-------------| | Memory Operations | generateShards, restoreFromShards, restoreShard | Work with Base64 data in memory | | File Operations | generateFileShards, restoreFromFileShards, restoreFileShard | Direct file-to-file operations | | Hybrid Operations | generateShardsToFiles, restoreFromFileShardsToData | Convert between memory and file formats |

generateShards(...)

generateShards(options: { totalShards: number; threshold: number; inputDataBase64: string; }, callback: (data?: { progress: number; shardsBase64?: string[] | undefined; } | undefined, error?: Error | undefined) => void) => Promise<void>

Splits secret data (Base64) into encrypted shards in memory.

| Param | Type | Description | | -------------- | ------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | | options | { totalShards: number; threshold: number; inputDataBase64: string; } | totalShards (≤255), threshold (≥2, ≤255), and inputDataBase64 (Base64-encoded secret) | | callback | (data?: { progress: number; shardsBase64?: string[]; }, error?: Error) => void | Reports progress and returns shards as Base64 strings |


restoreFromShards(...)

restoreFromShards(options: { inputShardsBase64: string[]; }, callback: (data?: { progress: number; dataBase64?: string | undefined; } | undefined, error?: Error | undefined) => void) => Promise<void>

Restores secret data from encrypted shards (all in memory, Base64).

| Param | Type | Description | | -------------- | --------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | | options | { inputShardsBase64: string[]; } | inputShardsBase64: array of Base64-encoded shards | | callback | (data?: { progress: number; dataBase64?: string; }, error?: Error) => void | Reports progress and returns restored secret as Base64 |


restoreShard(...)

restoreShard(options: { shardIndex: number; inputShardsBase64: string[]; }, callback: (data?: { progress: number; dataBase64?: string | undefined; } | undefined, error?: Error | undefined) => void) => Promise<void>

Restores a specific shard from a set of encrypted shards (all in memory, Base64).

| Param | Type | Description | | -------------- | --------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | | options | { shardIndex: number; inputShardsBase64: string[]; } | shardIndex (>0, ≤255) and inputShardsBase64 | | callback | (data?: { progress: number; dataBase64?: string; }, error?: Error) => void | Reports progress and returns the requested shard as Base64 |


generateFileShards(...)

generateFileShards(options: { totalShards: number; threshold: number; srcPath: string; dstPathRoot: string; }, callback: (data?: { progress: number; shardsPaths?: string[] | undefined; } | undefined, error?: Error | undefined) => void) => Promise<void>

Splits a file into encrypted shard files.

| Param | Type | Description | | -------------- | ------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------- | | options | { totalShards: number; threshold: number; srcPath: string; dstPathRoot: string; } | totalShards (≤255), threshold (≥2, ≤255), srcPath (input file), dstPathRoot (output directory) | | callback | (data?: { progress: number; shardsPaths?: string[]; }, error?: Error) => void | Reports progress and returns paths to shard files |


generateShardsToFiles(...)

generateShardsToFiles(options: { totalShards: number; threshold: number; inputDataBase64: string; dstPathRoot: string; }, callback: (data?: { progress: number; shardsPaths?: string[] | undefined; } | undefined, error?: Error | undefined) => void) => Promise<void>

Splits secret data (Base64) into encrypted shard files.

| Param | Type | Description | | -------------- | ------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------- | | options | { totalShards: number; threshold: number; inputDataBase64: string; dstPathRoot: string; } | totalShards (≤255), threshold (≥2, ≤255), inputDataBase64, dstPathRoot (output directory) | | callback | (data?: { progress: number; shardsPaths?: string[]; }, error?: Error) => void | Reports progress and returns paths to shard files |


restoreFromFileShards(...)

restoreFromFileShards(options: { shardsPaths: string[]; dstPath: string; }, callback: (data?: { progress: number; dstPath?: string | undefined; } | undefined, error?: Error | undefined) => void) => Promise<void>

Restores a file from encrypted shard files.

| Param | Type | Description | | -------------- | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------- | | options | { shardsPaths: string[]; dstPath: string; } | shardsPaths (input files), dstPath (output file) | | callback | (data?: { progress: number; dstPath?: string; }, error?: Error) => void | Reports progress and returns the output file path |


restoreFromFileShardsToData(...)

restoreFromFileShardsToData(options: { shardsPaths: string[]; }, callback: (data?: { progress: number; dataBase64?: string | undefined; } | undefined, error?: Error | undefined) => void) => Promise<void>

Restores secret data (Base64) from encrypted shard files.

| Param | Type | Description | | -------------- | --------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | | options | { shardsPaths: string[]; } | shardsPaths (input files) | | callback | (data?: { progress: number; dataBase64?: string; }, error?: Error) => void | Reports progress and returns restored secret as Base64 |


restoreFileShard(...)

restoreFileShard(options: { shardIndex: number; shardsPaths: string[]; dstPathRoot: string; }, callback: (data?: { progress: number; shardPath?: string | undefined; } | undefined, error?: Error | undefined) => void) => Promise<void>

Restores a specific shard file from a set of encrypted shard files.

| Param | Type | Description | | -------------- | -------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | | options | { shardIndex: number; shardsPaths: string[]; dstPathRoot: string; } | shardIndex (>0, ≤255), shardsPaths (input files), dstPathRoot (output directory) | | callback | (data?: { progress: number; shardPath?: string; }, error?: Error) => void | Reports progress and returns the path to the restored shard file |


Interfaces

Error

| Prop | Type | | ------------- | ------------------- | | name | string | | message | string | | stack | string |

License

This project is dual-licensed under MIT OR Apache-2.0. You may choose to use this project under the terms of either license.

This dual licensing approach is necessary because the web implementation includes code derived from simbo1905/shamir, which is licensed under the Apache License 2.0.

See the LICENSE file for the full legal text.

🛠️ Troubleshooting

Common Issues

Large File Performance

  • For files > 10MB, consider using file-based operations instead of memory-based
  • Monitor progress callbacks to provide user feedback during long operations

Base64 Encoding

  • Remember to encode/decode data properly when working with binary content

Platform Differences

  • File paths vary between platforms - use absolute paths when possible
  • iOS sandbox restrictions may limit file access locations

🧪 Testing

# Run unit tests
npm run test

# Run platform-specific test cases
npm run verify:ios
npm run verify:android

📱 Platform Support

| Platform | Version | Status | |----------|---------|--------| | iOS | 14.0+ | ✅ Fully supported | | Android | API 23+ | ✅ Fully supported | | Web | Modern browsers | ✅ Fully supported |

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Setup

# Clone the repository
git clone https://github.com/vault12/capacitor-shamir.git
cd capacitor-shamir

# Install dependencies
npm install

# Build the plugin
npm run build

# Run tests
npm test

📝 Changelog

See Releases for detailed changelog.

🙏 Acknowledgments

📞 Support