Pharmasplit: Drug Formula Protection
Pharmaceutical drug formulas represent billions in R&D investment. Pharmasplit uses XorIDA threshold sharing over GF(2) to split formula data into shares distributed across independent R&D sites. No single site holds a reconstructable formula. Reconstruction requires a threshold quorum of sites, and every share is HMAC-signed to detect tampering. Information-theoretic security for the most sensitive intellectual property in life sciences.
Executive Summary
Pharmasplit protects drug formulas via XorIDA threshold sharing — a cryptographic primitive that splits formula data into N shares such that any K shares can reconstruct the original, but K-1 or fewer shares reveal exactly zero information.
Two functions cover the complete workflow: splitFormula() takes a formula and configuration, returns N shares with SHA-256 hash verification. reconstructFormula() takes K or more shares, verifies HMAC integrity on each, reconstructs the plaintext, and returns the original formula data. Between split and reconstruct, shares are distributed to independent R&D sites in different jurisdictions.
Information-theoretic security by design. XorIDA operates over GF(2) — the binary field. Any K-1 or fewer shares reveal zero bits about the plaintext. Not computationally hard to break (there's nothing to break) — mathematically impossible to break, even with unlimited computing power or quantum computers.
HMAC before reconstruction. Every share carries an HMAC signature (SHA-256 keyed hash) verified before any reconstruction attempt. Tampered shares are rejected. Combined with geographic distribution, Pharmasplit prevents both accidental corruption and active tampering across all integrity threats.
The package provides configuration validation before any operation, enforcing safe split parameters (threshold bounds, minimum sites). No cryptographic operation proceeds if the configuration is invalid.
The Problem
Pharmaceutical formulas are prime targets for industrial espionage. A single leaked formula can destroy competitive advantage overnight, trigger regulatory action, and undermine years of R&D investment.
Current Approaches Fall Short
Centralized vaults. Storing the complete formula in a single secure database creates a single point of compromise. Breach = full loss. Access controls are policy-based, not cryptographic.
Encrypted at rest. AES-256-GCM encryption protects against passive observation, but the encryption key must exist somewhere. Key theft = plaintext recovery. Key rotation adds operational complexity.
Distributed copies. Replicating the formula across multiple R&D sites for redundancy increases attack surface. Each copy is a potential breach point. Synchronization introduces inconsistency and data integrity risks.
Air-gapped storage. Disconnecting systems from the network reduces attack surface but hurts collaboration. Researchers in different locations can't easily access shared formulas without manual courier processes.
Threshold Sharing Changes the Game
With Pharmasplit, no single breach is sufficient. A breach at one R&D site yields only one share. That share, in isolation, reveals zero information about the formula. An attacker must compromise a threshold (e.g., 2 of 3) of independent sites simultaneously to recover the formula.
| Property | Centralized Vault | Encrypted Copies | Pharmasplit |
|---|---|---|---|
| Single breach = formula loss | Yes | Yes (+ key theft) | No |
| Key rotation needed | Yes | Yes | No keys |
| Information-theoretic | No | No | Yes |
| Quantum-proof | No | No | Yes |
| Requires K-of-N breach | 1 of 1 | 1 of N | K of N (K > 1) |
The Solution: XorIDA Threshold Sharing
XorIDA splits a formula into N shares over GF(2) such that any K shares reconstruct the original, and any K-1 or fewer shares reveal zero information.
How It Works
Pharmasplit performs the following steps:
1. Generate HMAC key. A random 32-byte key is generated via crypto.getRandomValues(), never Math.random().
2. Split the formula. The formula data is split via XorIDA into N shares (e.g., N=3) such that K shares (e.g., K=2) are required for reconstruction. The splitting operation is deterministic: same input → same shares.
3. Sign each share. Each share is HMAC-signed using the random key. The HMAC covers the share index, total shares, threshold, formula ID, and the share data itself.
4. Distribute shares. Each share is delivered to a different R&D site via secure transport (encrypted HTTPS, VPN, or couriered storage). The HMAC key is stored separately (e.g., in a key escrow system or HSM) and never sent with the shares.
5. Reconstruct (later). When the formula is needed, K or more shares are collected from different sites. Each share's HMAC is verified independently. If all HMACs pass, the shares are reconstructed via XorIDA. The reconstructed data is guaranteed to match the original.
Security Properties
Why Pharmasplit is Different
No keys. Traditional encryption requires key management. Pharmasplit has no secret keys to rotate, compromise, or escrow. The split IS the security.
Geographic distribution. Shares are stored at independent R&D sites in different countries. An attacker must compromise multiple physical locations simultaneously to recover the formula.
Sub-millisecond overhead. XorIDA over GF(2) is fast. A 1MB formula splits in ~52ms and reconstructs in ~33ms. The operation is computation-bound, not I/O-bound, and suitable for real-time workflows.
Real-World Use Cases
Four scenarios where Pharmasplit protects pharmaceutical IP from industrial espionage and insider threats.
Three R&D labs in Boston, Basel, Tokyo. Each holds a 2-of-3 share. Formula is reconstructed only when all three labs sign off. A breach at one lab yields nothing.
splitFormula(..., threshold: 2)Drug formula held in escrow for patent litigation. Shares held by independent parties (law firm, bank, patent office). Only court order can trigger reconstruction.
Multi-party reconstructionPartnering companies each hold a share. Neither can access the formula unilaterally. Reconstruction requires consensus. Prevents unilateral IP theft.
Consensus-based accessDrug formulas stored per FDA/EMA regulations. Pharmasplit satisfies "secure, distributed storage" requirements. HMAC verification proves integrity for regulatory audits.
Audit-ready integrityArchitecture
Pharmasplit is built on five core modules composing into a single, auditable, testable system.
API & Integration
Three public functions + two type exports. Total public surface: 150 lines of code.
// Types export interface DrugFormula { formulaId: string; // Unique formula ID name: string; // Human-readable name version: string; // Semver recommended compound: string; // INN or IUPAC name data: Uint8Array; // Raw formula bytes } export interface PharmaConfig { sites: ResearchSite[]; // R&D sites threshold: number; // K-of-N for reconstruction } // Functions export async function splitFormula( formula: DrugFormula, config: PharmaConfig ): Promise<Result<FormulaSplitResult, PharmaError>> export async function reconstructFormula( shares: FormulaShare[] ): Promise<Result<Uint8Array, PharmaError>> export function validateConfig( config: PharmaConfig ): void // Throws on error
Complete Workflow Example
import { splitFormula, reconstructFormula, validateConfig } from '@private.me/pharmasplit'; // 1. Define three R&D sites const sites = [ { id: 'site-1', name: 'Boston Lab', location: 'Boston, MA' }, { id: 'site-2', name: 'Basel Center', location: 'Basel, Switzerland' }, { id: 'site-3', name: 'Tokyo Hub', location: 'Tokyo, Japan' }, ]; // 2. Configure 2-of-3 split const config = { sites, threshold: 2 }; validateConfig(config); // Throws if invalid // 3. Create formula object const formula = { formulaId: 'FORM-2026-XR7', name: 'Compound XR-7 Extended Release', version: '2.1.0', compound: 'methylphenidate', data: formulaBytes, // Uint8Array }; // 4. Split the formula const splitResult = await splitFormula(formula, config); if (!splitResult.ok) throw new Error(splitResult.error.message); // 5. Distribute to sites const { shares } = splitResult.value; await site1.storeShare(shares[0]); await site2.storeShare(shares[1]); await site3.storeShare(shares[2]); // 6. Later: reconstruct from any 2 shares const share1 = await site1.getShare('FORM-2026-XR7'); const share3 = await site3.getShare('FORM-2026-XR7'); const reconstructed = await reconstructFormula([share1, share3]); if (!reconstructed.ok) throw new Error(reconstructed.error.message); // Original formula data recovered const recoveredData = reconstructed.value; // Uint8Array
Configuration & Validation
Safe defaults. Enforced constraints. No operation proceeds with invalid configuration.
Configuration Rules
| Parameter | Constraint | Rationale |
|---|---|---|
sites.length |
≥ 2 | Single site is centralized (defeats purpose). Two sites minimum for any benefit. |
threshold |
≥ 2 | K=1 means a single share reconstructs the formula (no security improvement). |
threshold |
≤ sites.length | Can't require more shares than exist. |
formula.data |
Non-empty | Empty data has no meaning. Minimum 1 byte. |
Validation Function
validateConfig(config) is called automatically by splitFormula(), but can also be called explicitly for early error detection:
try { validateConfig({ sites: [{ id: 'only-one', name: 'Lonely Lab', location: 'Nowhere' }], threshold: 2 }); } catch (err) { console.error(err.message); // "Configuration is invalid. Check site count (>= 2), threshold (>= 2, <= sites)" }
Security
Information-theoretic, cryptographically verified, quantum-proof by design.
HMAC Before Reconstruction
Every share carries an HMAC signature. Before any reconstruction attempt, each share's HMAC is verified independently. The HMAC covers:
- The share data (base64-encoded)
- The share index and total shares (K-of-N parameters)
- The formula ID (prevents share mixing between formulas)
- The threshold
If a single bit of a share is corrupted or tampered with, the HMAC fails and the share is rejected. Reconstruction requires K valid shares. K-1 invalid + 1 valid = reconstruction fails.
Information-Theoretic Security
XorIDA over GF(2) provides Shannon perfect secrecy. This is NOT a property of encryption keys (which can be broken). It is a property of the split itself: K-1 or fewer shares reveal exactly zero information about the plaintext, regardless of computational power.
Cryptographic Primitives
| Operation | Algorithm | Standard | Purpose |
|---|---|---|---|
| Random key generation | crypto.getRandomValues() | Web Crypto API | Never Math.random() |
| Threshold splitting | XorIDA (GF(2)) | @private.me/crypto | Information-theoretic |
| HMAC signature | HMAC-SHA256 | @private.me/crypto | Integrity verification |
| Hash (formula ID) | SHA-256 | Web Crypto API | Deterministic formula hash |
No Math.random() Ever
Pharmasplit uses only crypto.getRandomValues() for all randomness. This is cryptographically secure randomness sourced from the OS CSPRNG (Crypto Service Provider). Math.random() is NOT used anywhere in the codebase, even for non-security-critical operations.
Performance & Benchmarks
Sub-millisecond splits. 52ms for 1MB. Zero network overhead in the package.
Measured Timings
| Operation | Size | Time | Notes |
|---|---|---|---|
| XorIDA split (2-of-2) | 64 bytes | <0.1ms | XOR-only, minimal overhead |
| XorIDA split (2-of-3) | 1 KB | <1ms | Typical formula metadata |
| XorIDA split (2-of-3) | 1 MB | ~52ms | Large binary formula data |
| HMAC-SHA256 (3 shares) | 1 MB total | ~15ms | Signing all shares |
| XorIDA reconstruct (2-of-3) | 1 MB | ~33ms | Including HMAC verification |
| Full split pipeline | 1 MB | ~70ms | Split + HMAC all shares |
| Full reconstruct pipeline | 1 MB | ~35ms | Verify + reconstruct |
Scaling Characteristics
XorIDA's XOR-based algorithm has linear time complexity: O(N) in data size and O(K) in share count. Doubling the formula size doubles the split time. Pharmasplit is I/O-bound for network distribution (not included in the package), not CPU-bound for cryptographic operations.
Error Handling
Six error codes. Result<T, E> pattern. Detailed, actionable messages.
Error Types
| Code | Meaning | Recovery |
|---|---|---|
| INVALID_CONFIG | Config validation failed (bad threshold, no sites, etc.) | Fix configuration, try again |
| SPLIT_FAILED | XorIDA split operation failed | Verify formula data integrity, retry |
| HMAC_FAILED | HMAC-SHA256 operation failed | Check system crypto availability, retry |
| RECONSTRUCT_FAILED | Share reconstruction produced invalid data | Verify shares are from same formula, retry |
| INSUFFICIENT_SHARES | Fewer shares provided than threshold requires | Collect more shares, retry |
| FORMULA_NOT_FOUND | Referenced formula does not exist | Verify formula ID, check storage |
Usage Pattern
const result = await splitFormula(formula, config); if (!result.ok) { const error = result.error; switch (error.code) { case 'INVALID_CONFIG': console.error('Configuration error', error.message); break; case 'SPLIT_FAILED': console.error('Cryptographic split failed', error.message); break; default: console.error('Unknown error', error.code, error.message); } return; } // result.value contains FormulaSplitResult with shares const { shares, formulaHash } = result.value;
Limitations
Pharmasplit is fit-for-purpose, not universal. Know the constraints.
Share Transport is Not Included
Pharmasplit produces shares and returns them as structured data. The package does NOT include transport to R&D sites (HTTPS delivery, VPN tunneling, physical courier). Developers must implement secure transport independently. Shares must be encrypted in transit using HTTPS, IPSec, or equivalent.
No Server-Side Share Storage
Pharmasplit does not persist shares to a database. The package is stateless. Developers are responsible for storing shares durably (database, HSM, cloud vault, etc.) and making them available during reconstruction.
No Key Escrow
The HMAC key is generated and returned inside the FormulaSplitResult. Developers must store the key securely (e.g., in a separate HSM or key vault) and supply it during reconstruction. Loss of the HMAC key invalidates all shares (they cannot be verified).
No Threshold Update
Once a formula is split, the K-of-N parameters are fixed. To change the threshold (e.g., from 2-of-3 to 3-of-5), the formula must be reconstructed, then re-split with new parameters. No in-place re-sharing.
Deterministic Output
XorIDA's split is deterministic: the same formula + same HMAC key + same K/N parameters always produce identical shares. This is a feature (reproducibility) but also a limitation: developers cannot re-split a formula to generate fresh shares with the same key. A new random HMAC key is required for each split.
Error Codes & Diagnostics
Detailed error reference with recovery strategies for each failure mode.
Complete Error Reference
| Code | Details | Recovery Strategy |
|---|---|---|
| INVALID_CONFIG | sites.length < 2, or threshold < 2, or threshold > sites.length | Ensure ≥2 sites, threshold between 2 and site count, try again |
| SPLIT_FAILED | XorIDA operation raised an exception (likely crypto unavailable) | Check Web Crypto API availability, ensure formula data is valid Uint8Array |
| HMAC_FAILED | HMAC-SHA256 failed (unlikely, usually crypto API error) | Verify system CSPRNG is available, retry after delay |
| RECONSTRUCT_FAILED | XorIDA reconstruction returned invalid/corrupted data | Verify all shares are from the same formula and same K-of-N configuration |
| INSUFFICIENT_SHARES | Fewer than K shares provided to reconstruct() | Collect additional shares until you have at least K, then retry |
| FORMULA_NOT_FOUND | Referenced formula ID does not exist in storage | Verify formula ID is correct, check if formula was deleted, try different storage |
Debugging Tips
Enable detailed logging: Wrap Pharmasplit calls in try-catch and log all error codes and messages. Include the error code in logs so you can correlate with the table above.
Validate configuration early: Call validateConfig() explicitly before splitFormula() to catch configuration errors immediately.
Test share distribution: After splitting, immediately attempt reconstruction with a valid subset of shares to verify the pipeline is working before distributing to production R&D sites.
Codebase Statistics
Module Breakdown
types.ts— 70 lines. All public interfaces and discriminated union error types.errors.ts— 88 lines. Error class hierarchy and conversion utilities.validate.ts— 30 lines. Configuration validation function.formula-splitter.ts— 120 lines. Main split pipeline.formula-reconstructor.ts— 100 lines. Reconstruction and HMAC verification.index.ts— Barrel export, 20 lines.__tests__/— 4 test files: formula-splitter.test.ts, reconstruct tests, validation tests, abuse tests.
Total source: ~400 lines. Tests: ~700 lines. Ratio: 1.75:1 (tests:source). No external npm dependencies beyond @private.me/crypto and Web Crypto API.
Deployment Options
SaaS Recommended
Fully managed infrastructure. Call our REST API, we handle scaling, updates, and operations.
- Zero infrastructure setup
- Automatic updates
- 99.9% uptime SLA
- Enterprise SLA available
SDK Integration
Embed directly in your application. Runs in your codebase with full programmatic control.
npm install @private.me/pharmasplit- TypeScript/JavaScript SDK
- Full source access
- Enterprise support available
On-Premise Upon Request
Enterprise CLI for compliance, air-gap, or data residency requirements.
- Complete data sovereignty
- Air-gap capable deployment
- Custom SLA + dedicated support
- Professional services included
Enterprise On-Premise Deployment
While pharmaSplit is primarily delivered as SaaS or SDK, we build dedicated on-premise infrastructure for customers with:
- Regulatory mandates — HIPAA, SOX, FedRAMP, CMMC requiring self-hosted processing
- Air-gapped environments — SCIF, classified networks, offline operations
- Data residency requirements — EU GDPR, China data laws, government mandates
- Custom integration needs — Embed in proprietary platforms, specialized workflows
Includes: Enterprise CLI, Docker/Kubernetes orchestration, RBAC, audit logging, and dedicated support.