CharlZKP/shamirs-secret-sharing-swift-privyio
Swift implementation of Shamir's Secret Sharing scheme, ported from Privy.io's TypeScript/JavaScript library. Split secrets into shares where any k shares can reconstruct the original, but fewer than k shares reveal nothing.
What is Shamir's Secret Sharing?
Shamir's Secret Sharing is a cryptographic algorithm that allows you to split a secret into multiple shares such that:
- Any
kshares can reconstruct the original secret (wherekis the threshold) - Fewer than
kshares reveal absolutely nothing about the secret - Perfect security: Even with unlimited computational power, having fewer than
kshares provides zero information
This is perfect for scenarios like:
- π Backup recovery keys - Split your master key among trusted friends
- π’ Corporate secrets - Require multiple executives to access critical data
- π Multi-signature wallets - Distribute cryptocurrency access
- π± Secure storage - Store shares across different devices/locations
Quick Start
Swift Package Manager
Add this to your Package.swift:
dependencies: [
.package(url: "https://github.com/CharlZKP/shamirs-secret-sharing-swift-privyio", from: "1.0.0")
],
targets: [
.target(
name: "YourTarget",
dependencies: ["ShamirsSecretSharingPrivy"]
)
]Or in Xcode: File β Add Package Dependencies and enter the repository URL.
Basic Usage
import ShamirsSecretSharingPrivy
// Your secret
let secret = "my super secret password".data(using: .utf8)!
// Split into 5 shares, requiring any 3 to reconstruct
let shares = try ShamirsSecretSharing.split(
secret: secret,
shares: 5,
threshold: 3
)
// Later... reconstruct using any 3 shares
let reconstructed = try ShamirsSecretSharing.combine(
shares: [shares[0], shares[2], shares[4]]
)
let originalSecret = String(data: reconstructed, encoding: .utf8)!
// "my super secret password"Command Line Interface
The package includes a powerful CLI tool for easy command-line usage.
Installation
git clone https://github.com/CharlZKP/shamirs-secret-sharing-swift-privyio
cd shamirs-secret-sharing-swift-privyio
swift build -c releaseThe CLI will be available at .build/release/shamir-privy-cli.
CLI Examples
Split a secret:
./shamir-privy-cli split "Hello World" 5 3Output:
Secret split successfully!
Shares (Base64 encoded):
Share 1: xtmHmbgvA5xbMlGl
Share 2: ad5cp1AiSRxNGMAR
Share 3: PvmUa/efheCPgXrf
Share 4: QnB2K8fvZqxoHlMw
Share 5: RpF3L9gwaqypIlNx
To reconstruct the secret, use any 3 of these shares:
shamir-privy-cli combine "xtmHmbgvA5xbMlGl" "ad5cp1AiSRxNGMAR" "PvmUa/efheCPgXrf"Reconstruct the secret:
./shamir-privy-cli combine "xtmHmbgvA5xbMlGl" "ad5cp1AiSRxNGMAR" "PvmUa/efheCPgXrf"Output:
Secret reconstructed successfully!
Original secret: "Hello World"Cross-Platform Compatibility
This Swift implementation is fully compatible with Privy.io's JavaScript/TypeScript library. You can:
- β Split secrets in JavaScript and reconstruct in Swift
- β Split secrets in Swift and reconstruct in JavaScript
- β Use the same shares across both implementations
- β Mix and match CLI tools from both languages
Compatibility Example
JavaScript (Node.js):
const { split } = require('@privy-io/shamir-secret-sharing');
const secret = new Uint8Array([72, 101, 108, 108, 111]); // "Hello"
const shares = await split(secret, 3, 2);
// shares can be used in Swift!Swift:
// Use the shares from JavaScript
let shares = [/* Base64 shares from JS */]
let shareData = shares.compactMap { Data(base64Encoded: $0) }
let reconstructed = try ShamirsSecretSharing.combine(shares: shareData)
// Reconstructs to "Hello"API Reference
ShamirsSecretSharing.split(secret:shares:threshold:)
Splits a secret into multiple shares.
Parameters:
secret: Data- The secret data to split (cannot be empty)shares: Int- Total number of shares to create (2-255)threshold: Int- Minimum shares needed for reconstruction (2-255)
Returns: [Data] - Array of shares (each share is secret.count + 1 bytes)
Throws: ShamirError for invalid inputs
ShamirsSecretSharing.combine(shares:)
Reconstructs the original secret from shares.
Parameters:
shares: [Data]- Array of shares (2-255 shares, all same length)
Returns: Data - The reconstructed secret
Throws: ShamirError for invalid inputs
Error Handling
do {
let shares = try ShamirsSecretSharing.split(secret: data, shares: 5, threshold: 3)
let reconstructed = try ShamirsSecretSharing.combine(shares: shares)
} catch ShamirError.emptySecret {
print("Secret cannot be empty")
} catch ShamirError.invalidInput(let message) {
print("Invalid input: \(message)")
} catch ShamirError.duplicateShares {
print("Shares must be unique")
} catch {
print("Unexpected error: \(error)")
}Technical Details
Mathematical Foundation
- Galois Field GF(2^8) arithmetic with irreducible polynomial: xβΈ + xβ΄ + xΒ³ + x + 1
- Lagrange interpolation for secret reconstruction
- Horner's method for efficient polynomial evaluation
- Lookup tables for O(1) field operations (same as Privy.io implementation)
Security Features
- Cryptographically secure random number generation using
SecRandomCopyBytes(macOS/iOS) or/dev/urandom(Linux) - Perfect secrecy: Shares below threshold reveal zero information
- Share format: Each share contains the polynomial evaluation + x-coordinate
- Memory safety: Automatic memory management via Swift's ARC
Performance
- O(1) field operations using pre-computed lookup tables
- O(nΒ²) complexity for split/combine operations
- Memory efficient using Swift's
Datatype - Cross-platform optimized for Apple devices and Linux
Platform Support
- macOS 10.15+
- iOS 13.0+
- tvOS 13.0+
- watchOS 6.0+
- Linux (Ubuntu, CentOS, etc.)
Testing
Run the comprehensive test suite:
swift testThe tests include:
- β Compatibility tests with provided test vectors
- β Input validation for all error conditions
- β Functional tests matching the JavaScript test suite
- β Edge cases (1-byte secrets, maximum shares, large secrets)
- β Galois Field operation verification
- β Base64 encoding/decoding for CLI compatibility
- β Unicode support including emojis
Real-World Examples
Cryptocurrency Wallet Backup
let privateKey = "your-private-key-here".data(using: .utf8)!
let shares = try ShamirsSecretSharing.split(secret: privateKey, shares: 7, threshold: 4)
// Give shares to 7 trusted friends
// Any 4 can help you recover your walletCorporate Database Password
let dbPassword = "super-secure-db-password".data(using: .utf8)!
let shares = try ShamirsSecretSharing.split(secret: dbPassword, shares: 5, threshold: 3)
// Distribute to 5 executives
// Any 3 must agree to access the databaseFamily Photo Encryption Key
let encryptionKey = generateRandomKey() // Your encryption key
let shares = try ShamirsSecretSharing.split(secret: encryptionKey, shares: 4, threshold: 2)
// Store shares on: iPhone, iPad, Mac, iCloud
// Any 2 devices can decrypt your photosContributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Add tests for new functionality
- Ensure all tests pass (
swift test) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project maintains the same license as the original Privy.io implementation.
Acknowledgments
- Privy.io - Original TypeScript/JavaScript implementation
- HashiCorp Vault - Galois Field lookup table reference
- Adi Shamir - Creator of Shamir's Secret Sharing scheme
Package Metadata
Repository: CharlZKP/shamirs-secret-sharing-swift-privyio
Stars: 0
Forks: 0
Open issues: 0
Default branch: master
Primary language: swift
Topics: cryptography, secret-sharing, shamir-secret-sharing, swift, threshold-cryptography
README: README.md