initial
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
// Platform-agnostic crypto backend contract. Each host (desktop / mobile)
|
||||
// registers its own implementation at boot via `setCryptoBackend`.
|
||||
//
|
||||
// Why an interface?
|
||||
// - Desktop: libsodium-wrappers (WASM, needs async ready-gate).
|
||||
// - Mobile: react-native-libsodium (native bindings, different API shape).
|
||||
// - Tests: deterministic backend with seeded RNG.
|
||||
//
|
||||
// Backends are expected to be *synchronous* after registration. Any async
|
||||
// initialisation (e.g. libsodium's WASM warm-up) happens before the backend
|
||||
// object is handed to `setCryptoBackend`.
|
||||
|
||||
export interface KeyPair {
|
||||
publicKey: Uint8Array;
|
||||
privateKey: Uint8Array;
|
||||
}
|
||||
|
||||
export interface CryptoBackend {
|
||||
readonly name: string;
|
||||
readonly nonceLength: number; // crypto_box_NONCEBYTES — 24
|
||||
readonly publicKeyLength: number; // 32
|
||||
readonly privateKeyLength: number; // 32
|
||||
readonly secretboxKeyLength: number; // crypto_secretbox_KEYBYTES — 32
|
||||
readonly secretboxNonceLength: number; // crypto_secretbox_NONCEBYTES — 24
|
||||
|
||||
randomBytes(n: number): Uint8Array;
|
||||
generateKeyPair(): KeyPair;
|
||||
|
||||
// Authenticated encryption (X25519 + XSalsa20-Poly1305, AKA crypto_box).
|
||||
box(
|
||||
plaintext: Uint8Array,
|
||||
nonce: Uint8Array,
|
||||
recipientPublicKey: Uint8Array,
|
||||
senderPrivateKey: Uint8Array,
|
||||
): Uint8Array;
|
||||
|
||||
// Must throw on authentication failure.
|
||||
boxOpen(
|
||||
ciphertext: Uint8Array,
|
||||
nonce: Uint8Array,
|
||||
senderPublicKey: Uint8Array,
|
||||
recipientPrivateKey: Uint8Array,
|
||||
): Uint8Array;
|
||||
|
||||
// Symmetric authenticated encryption (XSalsa20-Poly1305, crypto_secretbox).
|
||||
// Used for large blobs (attachments) — one key per blob, key itself is
|
||||
// distributed per recipient via crypto_box envelopes.
|
||||
secretbox(plaintext: Uint8Array, nonce: Uint8Array, key: Uint8Array): Uint8Array;
|
||||
secretboxOpen(ciphertext: Uint8Array, nonce: Uint8Array, key: Uint8Array): Uint8Array;
|
||||
}
|
||||
|
||||
let current: CryptoBackend | null = null;
|
||||
|
||||
export function setCryptoBackend(backend: CryptoBackend): void {
|
||||
current = backend;
|
||||
}
|
||||
|
||||
export function getCryptoBackend(): CryptoBackend {
|
||||
if (!current) {
|
||||
throw new Error(
|
||||
'Crypto backend not configured. Call setCryptoBackend() at app boot before any crypto operation.',
|
||||
);
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
export function isCryptoBackendReady(): boolean {
|
||||
return current !== null;
|
||||
}
|
||||
Reference in New Issue
Block a user