@tamer4lynx/tamer-crypto

Web Crypto–shaped API for Lynx with native iOS/Android crypto. Supports SHA, AES-GCM, HMAC, PBKDF2, HKDF, ECDSA P-256, and RSA-OAEP via native modules with a JS fallback.

Install

t4l add tamer-crypto
t4l link

Usage

Polyfill globalThis.crypto

The easiest integration — patches globalThis.crypto so existing code using the Web Crypto API works without changes:

import { polyfillGlobalCrypto } from '@tamer4lynx/tamer-crypto';

polyfillGlobalCrypto(); // call once at app startup

Explicit instance

import { getTamerCrypto } from '@tamer4lynx/tamer-crypto';

const crypto = getTamerCrypto();

// random values
const bytes = new Uint8Array(16);
crypto.getRandomValues(bytes);

// UUID
const id = crypto.randomUUID();

// SubtleCrypto
const hash = await crypto.subtle.digest('SHA-256', data);

TamerCrypto class

import { TamerCrypto } from '@tamer4lynx/tamer-crypto';

const crypto = new TamerCrypto();
crypto.getRandomValues(buf);
crypto.randomUUID();
crypto.timingSafeEqual(a, b); // constant-time comparison

SubtleCrypto operations

All subtle methods follow the Web Crypto spec. Supported algorithms:

AlgorithmOperations
SHA-256 / SHA-384 / SHA-512digest
AES-GCMencrypt, decrypt, generateKey, importKey, exportKey
HMACsign, verify, generateKey, importKey, exportKey
PBKDF2deriveKey, deriveBits
HKDFderiveKey, deriveBits
ECDSA P-256sign, verify, generateKey, importKey, exportKey
RSA-OAEPencrypt, decrypt, generateKey, importKey, exportKey

wrapKey and unwrapKey are not supported.

// AES-GCM encrypt / decrypt
const key = await crypto.subtle.generateKey({ name: 'AES-GCM', length: 256 }, true, ['encrypt', 'decrypt']);
const iv = crypto.getRandomValues(new Uint8Array(12));
const ciphertext = await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, key, plaintext);
const plaintext2 = await crypto.subtle.decrypt({ name: 'AES-GCM', iv }, key, ciphertext);

// ECDSA sign / verify
const { privateKey, publicKey } = await crypto.subtle.generateKey({ name: 'ECDSA', namedCurve: 'P-256' }, false, ['sign', 'verify']);
const sig = await crypto.subtle.sign({ name: 'ECDSA', hash: 'SHA-256' }, privateKey, data);
const ok  = await crypto.subtle.verify({ name: 'ECDSA', hash: 'SHA-256' }, publicKey, sig, data);

API

ExportDescription
getTamerCrypto()Returns a Crypto-compatible singleton (native when available, JS fallback otherwise)
polyfillGlobalCrypto()Patches globalThis.crypto with the Tamer implementation
TamerCryptoClass implementing CryptogetRandomValues, randomUUID, timingSafeEqual, subtle
createTamerCryptoKey(...)Create a CryptoKey from raw material
hasNativeCrypto()Returns true when the native module is available

Native fallback

When the native module (TamerCryptoModule) is unavailable, getTamerCrypto() falls back to globalThis.crypto if present, then to the JS implementation. hasNativeCrypto() lets you branch on availability.