Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

unsea

draeder78MIT1.1.2

Platform-agnostic cryptographic utility toolkit for ephemeral identity, secure messaging, and portable key management — built on WebCrypto + noble-curves.

crypto, cryptography, webcrypto, p256, ecdsa, ecdh, aes-gcm, encryption, signing, verification, jwk, pem, pkcs8, pbkdf2, indexeddb, browser, nodejs, ephemeral, identity, messaging, key-management, noble-curves, proof-of-work, rate-limiting, anti-spam, computational-proof, pow, sha256, security, input-validation, constant-time, timing-attack-resistant

readme

Unsea

Platform-agnostic cryptograFor ES modules in the browser: `html

<script type="module"> import * as unsea from 'https://unpkg.com/unsea/dist/unsea.mjs'; const keys = await unsea.generateRandomPair(); console.log(keys); </script>

### Local Development
```bash
# Clone and setup
git clone https://github.com/draeder/unsea.git
cd unsea
npm install

# Setup development environment (configures git hooks, etc.)
npm run ci:setup

# Development server (for testing in browser)
npm run dev
# Opens http://localhost:5173/ with live testing interface

# Build the library
npm run build

# Run examples and tests
npm run example
npm test

# Security audit
npm run security:audit

Contributing

This project uses a comprehensive CI/CD pipeline to ensure code quality and security:

  • 🔍 Automated Security Scanning: Every commit is scanned for vulnerabilities
  • 🧪 Multi-Platform Testing: Tests run on Linux, Windows, and macOS
  • 🌐 Browser Compatibility: Automated browser testing with multiple engines
  • 📦 Package Integrity: Validates package installation and imports
  • 🚦 Pre-commit Hooks: Local validation before commits
  • 👥 Required Reviews: All changes must be reviewed before merging

See CI/CD Documentation for detailed information.

---ity toolkit for ephemeral identity, secure messaging, and portable key management — built on WebCrypto + noble-curves.

🔐 Features

  • 🔑 Deterministic or random P-256 keypair generation
  • ✍️ Message signing and verification (ECDSA)
  • 🔒 Message encryption and decryption (ECDH + AES-GCM)
  • 📦 Encrypted message metadata: sender pubkey and timestamp
  • 🔁 Export/import keys to JWK and PEM formats (PKCS#8 compliant)
  • 💾 Encrypted IndexedDB persistence with password protection
  • ⛏️ Proof-of-work generation and verification (SHA-256 based mining)
  • 📝 Signed proof-of-work with cryptographic attestation
  • 🛡️ Enhanced security: input validation, constant-time operations, proper error handling
  • 📦 Bundled with Vite for optimal performance and security
  • ⚙️ Multiple formats: ES modules (.mjs), CommonJS (.cjs), and UMD (.js) for maximum compatibility
  • 🌐 Cross-platform: Works seamlessly in Node.js and modern browsers

📦 Installation

npm install unsea

Or use directly in the browser via CDN:

<script src="https://cdn.jsdelivr.net/npm/unsea/dist/unsea.umd.js"></script>
<script>
  // UMD version exposes Unsea globally
  const keys = await Unsea.generateRandomPair();
  console.log(keys);
</script>

For ES modules in the browser:

<script type="module">
  import * as unsea from 'https://cdn.jsdelivr.net/npm/unsea/dist/unsea.mjs';

  const keys = await unsea.generateRandomPair();
  console.log(keys);
</script>

� Build Architecture

Unsea uses Vite for modern bundling with multiple output formats:

Format File Environment Usage
ES Modules dist/unsea.mjs Modern Node.js, browsers import * as unsea from 'unsea'
CommonJS dist/unsea.cjs Traditional Node.js const unsea = require('unsea')
UMD dist/unsea.umd.js Browsers (global) <script src="...">Unsea.generateRandomPair()

Benefits of Bundled Approach

  • 🚀 Faster loading - No dynamic imports at runtime
  • 🔒 Better security - All dependencies statically analyzed
  • 📦 Smaller bundles - Tree-shaking removes unused code
  • Reliable - No network dependencies or import failures
  • 🌐 Universal - Works consistently across all environments

Development Mode

For development and testing, you can use the built-in development server:

npm run dev

This starts a Vite development server with:

  • 🔄 Hot reload - Automatic updates when source code changes
  • 🧪 Live testing interface - Interactive browser testing environment
  • 🐛 Source maps - Debug directly in the original source code
  • Fast compilation - Near-instant updates during development

The development server serves the library directly from src/index.js without bundling, making it perfect for rapid development and testing.


�🚀 Quick Start

# Install the package
npm install unsea

# Build the library
npm run build

# Run the example
npm run example

# Run tests
npm test

🧪 Example Usage

import {
  generateRandomPair,
  signMessage,
  verifyMessage,
  encryptMessageWithMeta,
  decryptMessageWithMeta,
  exportToPEM,
  importFromPEM,
  exportToJWK,
  importFromJWK,
  saveKeys,
  loadKeys,
  clearKeys,
  generateWork,
  verifyWork,
  generateSignedWork,
  verifySignedWork,
  getSecurityInfo
} from 'unsea';

const keys = await generateRandomPair();
// Secure encrypted storage
await saveKeys('default', keys, 'your-strong-password');

const msg = 'Hello, Unsea!';
const sig = await signMessage(msg, keys.priv);
const valid = await verifyMessage(msg, sig, keys.pub);

const encrypted = await encryptMessageWithMeta(msg, keys);
const decrypted = await decryptMessageWithMeta(encrypted, keys.epriv);

// Get security information
console.log(getSecurityInfo());

console.log({ valid, decrypted });

🔁 Export / Import Keys

const pem = await exportToPEM(keys.priv);
const restoredPriv = await importFromPEM(pem);

const jwk = await exportToJWK(keys.priv);
const restoredFromJwk = await importFromJWK(jwk);

💾 Key Persistence (Browser Only)

await saveKeys('profile1', keys);
const loaded = await loadKeys('profile1');
await clearKeys('profile1');

🧩 Message Metadata Format

{
  "ciphertext": "...",
  "iv": "...",
  "sender": "base64url(x.y)",
  "timestamp": 1723981192738
}

⛏️ Proof of Work

// Generate proof of work (for rate limiting, anti-spam, etc.)
const data = { challenge: 'computational_proof', user: 'alice' };
const work = await generateWork(data, difficulty = 4, maxIterations = 1000000);
console.log(work);
// {
//   data: '{"challenge":"computational_proof","user":"alice"}',
//   nonce: 12847,
//   hash: 'ABC123...',
//   hashHex: '0000a1b2c3...',
//   difficulty: 4,
//   timestamp: 1723981192738,
//   duration: 2341,
//   hashRate: 5489
// }

// Verify proof of work
const verification = await verifyWork(work);
console.log(verification.valid); // true

// Generate signed proof of work (authenticated computational proof)
const keys = await generateRandomPair();
const signedWork = await generateSignedWork(data, keys.priv, difficulty = 4);
console.log(signedWork.signature);

// Verify signed proof of work
const signedVerification = await verifySignedWork(signedWork, keys.pub);
console.log(signedVerification.valid); // true

📁 Project Structure

unsea/
├── src/
│   └── index.js          # Main library source code
├── dist/                 # Built library files (generated)
│   ├── unsea.mjs         # ES modules
│   ├── unsea.cjs         # CommonJS
│   └── unsea.umd.js      # UMD for browsers
├── example/
│   └── example.js        # Usage examples and demos
├── test/
│   └── test.js          # Comprehensive test suite  
├── index.html            # Development server interface
├── vite.config.js        # Build configuration
├── README.md
├── SECURITY.md
├── package.json
└── LICENSE

Run npm run example to see all features in action!


⚙️ Internals

  • Uses dynamic import() for browser/Node compatibility
  • WebCrypto subtle for hashing + AES
  • @noble/curves/p256 for EC operations
  • Base64url encoding utilities for compact key/IV/sig serialization

🛡️ Security

This library implements several security best practices:

  • Bundled Dependencies: Static imports eliminate runtime dependency risks
  • Encrypted Key Storage: Keys can be encrypted with PBKDF2 before storage
  • Input Validation: All inputs are validated and sanitized
  • Constant-Time Operations: Hash comparisons use constant-time algorithms
  • Proper Error Handling: No sensitive data leaked in error messages
  • PKCS#8 Compliance: PEM format follows cryptographic standards

For detailed security information, see SECURITY.md.


🔁 Secure Key Storage

// Encrypted storage (recommended)
const password = 'your-strong-password';
await saveKeys('profile', keys, password);
const loadedKeys = await loadKeys('profile', password);

// Unencrypted storage (shows warning)
await saveKeys('profile', keys);
const loadedKeys = await loadKeys('profile');

License

MIT © 2025