Contents

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 k shares can reconstruct the original secret (where k is the threshold)
  • Fewer than k shares reveal absolutely nothing about the secret
  • Perfect security: Even with unlimited computational power, having fewer than k shares 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 release

The CLI will be available at .build/release/shamir-privy-cli.

CLI Examples

Split a secret:

./shamir-privy-cli split "Hello World" 5 3

Output:

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 Data type
  • 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 test

The 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 wallet

Corporate 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 database

Family 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 photos

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Add tests for new functionality
  4. Ensure all tests pass (swift test)
  5. Commit your changes (git commit -m 'Add amazing feature')
  6. Push to the branch (git push origin feature/amazing-feature)
  7. Open a Pull Request

License

This project maintains the same license as the original Privy.io implementation.

Acknowledgments

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