import { MaybeAsync } from '../../types' import { AesModeOfOperationIge } from './common' import { factorizePQSync } from './factorization' export interface IEncryptionScheme { encrypt(data: Buffer): MaybeAsync decrypt(data: Buffer): MaybeAsync } export interface IHashMethod { update(data: Buffer): MaybeAsync digest(): MaybeAsync } export interface ICryptoProvider { initialize?(): MaybeAsync sha1(data: Buffer): MaybeAsync sha256(data: Buffer): MaybeAsync pbkdf2( password: Buffer, salt: Buffer, iterations: number ): MaybeAsync hmacSha256(data: Buffer, key: Buffer): MaybeAsync // in telegram, iv is always either used only once, or is the same for all calls for the key createAesCtr(key: Buffer, iv: Buffer, encrypt: boolean): IEncryptionScheme createAesIge(key: Buffer, iv: Buffer): IEncryptionScheme createAesEcb(key: Buffer): IEncryptionScheme createMd5(): IHashMethod factorizePQ(pq: Buffer): MaybeAsync<[Buffer, Buffer]> } export abstract class BaseCryptoProvider implements ICryptoProvider { createAesIge(key: Buffer, iv: Buffer): IEncryptionScheme { return new AesModeOfOperationIge(key, iv, this.createAesEcb(key)) } factorizePQ(pq: Buffer): MaybeAsync<[Buffer, Buffer]> { return factorizePQSync(pq) } initialize(): void {} abstract createAesCtr( key: Buffer, iv: Buffer, encrypt: boolean ): IEncryptionScheme abstract createAesEcb(key: Buffer): IEncryptionScheme // algo: sha1 or sha512 (default sha512) abstract pbkdf2( password: Buffer, salt: Buffer, iterations: number, keylen?: number, // = 64 algo?: string ): MaybeAsync abstract sha1(data: Buffer): MaybeAsync abstract sha256(data: Buffer): MaybeAsync abstract hmacSha256(data: Buffer, key: Buffer): MaybeAsync abstract createMd5(): IHashMethod } export type CryptoProviderFactory = () => ICryptoProvider