lava-seal
v1.0.0
Published
Browser crypto with visual entropy capture from live webpage
Maintainers
Readme
lava-seal
Browser encryption seeded with visual entropy from a live webpage.
Install
npm install lava-sealAPI
captureLavaEntropy(url?: string): Promise<ArrayBuffer>: Captures visual entropy from a URL (default: https://lava-entropy-wall.vercel.app/) and returns a SHA-256 hash of pixels.mixEntropy(screenshotHash: ArrayBuffer, localBytes?: Uint8Array): Promise<ArrayBuffer>: Mixes screenshot hash, local RNG, and timestamp with SHA-512.deriveKey(seed: ArrayBuffer, salt?: Uint8Array, info?: Uint8Array): Promise<CryptoKey>: Derives an AES-GCM 256-bit key via HKDF(SHA-256).encrypt(data: Uint8Array, key: CryptoKey): Promise<{iv: Uint8Array, ciphertext: Uint8Array}>decrypt(ciphertext: Uint8Array, key: CryptoKey, iv: Uint8Array): Promise<Uint8Array>
Example
import { captureLavaEntropy, mixEntropy, deriveKey, encrypt, decrypt } from 'lava-seal';
const screenshot = await captureLavaEntropy();
const seed = await mixEntropy(screenshot);
const key = await deriveKey(seed);
const message = new TextEncoder().encode('Lava Lamps are random!');
const { iv, ciphertext } = await encrypt(message, key);
const plain = await decrypt(ciphertext, key, iv);
console.log(new TextDecoder().decode(plain)); // 'Lava Lamps are random!'Notes
- Works in modern browsers with Web Crypto API.
- Screenshot capture prefers drawing the target URL as an image to a canvas. If that fails (CORS, CSP), it attempts an off-screen iframe +
html2canvas. As a final fallback, it returns locally generated random bytes so the flow can continue. - The pixel data is downsampled to keep it lightweight before hashing.
