Loading...
private.me Docs
Get Pharmasplit
PRIVATE.ME · Technical White Paper

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.

v0.1.0 70+ tests passing 8 modules 0 npm deps <1ms splits HMAC verified
Section 01

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.

Section 02

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.

The Core Threat
An attacker who breaches a single location and obtains a complete formula copy has won. Whether that copy is encrypted, access-controlled, or replicated doesn't matter — one breach = total compromise.

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)
Section 03

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

Integrity
HMAC Verified
SHA-256 HMAC per share
Verified before reconstruction
Catches tampered shares
Detects accidental corruption

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.

Section 04

Real-World Use Cases

Four scenarios where Pharmasplit protects pharmaceutical IP from industrial espionage and insider threats.

🔬
Pharma
Multi-Site R&D

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)
🔐
IP Protection
Secure Escrow

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 reconstruction
🤝
Partnership
Joint Ventures

Partnering companies each hold a share. Neither can access the formula unilaterally. Reconstruction requires consensus. Prevents unilateral IP theft.

Consensus-based access
💡
Regulatory
Compliance Storage

Drug formulas stored per FDA/EMA regulations. Pharmasplit satisfies "secure, distributed storage" requirements. HMAC verification proves integrity for regulatory audits.

Audit-ready integrity
Section 05

Architecture

Pharmasplit is built on five core modules composing into a single, auditable, testable system.

Formula Reconstructor
Recovery Path
Accepts K or more FormulaShare objects
Verifies HMAC on each share
Calls XorIDA reconstruct
Returns Uint8Array plaintext
Config Validator
Safety Gate
Validates site count (≥ 2)
Validates threshold (≥ 2, ≤ sites)
Throws on invalid configuration
No operation proceeds without validation
Error Hierarchy
Diagnostics
6 discriminated union error types
PharmaSplitError base class
Named classes for each error category
Human-readable messages + URLs
Crypto Dependencies
External
@private.me/crypto — XorIDA + HMAC
Web Crypto API — SHA-256
crypto.getRandomValues() — RNG
No other npm dependencies
Section 06

API & Integration

Three public functions + two type exports. Total public surface: 150 lines of code.

Core API
// 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

Split, distribute, reconstruct
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
Section 07

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:

Explicit validation
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)"
}
Section 08

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.

Quantum-Proof by Construction
Quantum computers don't help. There's nothing to break. K-1 shares are information-theoretically indistinguishable from random data. No algorithm, quantum or classical, can extract information from nothing.

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.

Section 09

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.

Production-Ready Latency
For typical pharmaceutical formulas (10KB–1MB), split and reconstruct complete in under 100ms total. Network distribution (HTTPS to R&D sites) will dominate total wall-clock time, not cryptography.
Section 10

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

Error handling
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;
Section 11

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.

Share Verification Requires the HMAC Key
HMAC verification cannot happen without the HMAC key. If the key is lost or compromised, shares cannot be verified (and reconstruction fails). Store the HMAC key separately from the shares with equal protection.
Appendix A

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.

Appendix B

Codebase Statistics

8
TypeScript modules
70+
Test cases
0
npm dependencies
6
Error types
100%
Line coverage target

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

📦

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
Get Started →
🏢

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
Request Quote →

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.

Contact sales for assessment and pricing →