import { workerHandler } from "src/app/shared/worker-handler/worker-handler";
import { WorkerOperation } from 'src/app/shared/worker-handler/worker-common';
import { AESCipherCBCWorker, AESCipherGCMWorker, AESCipherSIVDeterministicWorker, AESCipherSIVNonce96Worker } from 'src/app/shared/crypto/worker_base/cipher/aes';




/**
 * Primary SIV cipher config with a medium sized nonce for extra security.
 */
export class AESCipherSIVNonce96 /*extends AESCipherSIVNonce96Worker*/{
    public static encrypt(plain: Uint8Array, key: Uint8Array, nonce?: Uint8Array, assoc: Uint8Array = new Uint8Array([]), prefix: Uint8Array = new Uint8Array([])): Promise<Uint8Array>{
        return workerHandler.run(WorkerOperation.AESCipherSIVNonce96Encrypt, plain, key, nonce, assoc, prefix);
    }

    public static decrypt(cipher: Uint8Array, key: Uint8Array, assoc: Uint8Array = new Uint8Array([])): Promise<Uint8Array>{
        return workerHandler.run(WorkerOperation.AESCipherSIVNonce96Decrypt, cipher, key, assoc);
    }

    public static describe(): string{
        return "AES-SIV-N96-128/256";
    }
}

/**
 * Deterministic SIV encryption by not using a nonce.
    RFC5297 Section 4:
    In case AES SIV is used for key wrapping it is not necessary to provide a nonce component.
 */
export class AESCipherSIVDeterministic /*extends AESCipherSIVDeterministicWorker*/{

    public static encrypt(plain: Uint8Array, key: Uint8Array, assoc?: Uint8Array, prefix: Uint8Array = new Uint8Array([])): Promise<Uint8Array>{
        return workerHandler.run(WorkerOperation.AESCipherSIVDeterministicEncrypt, plain, key, assoc, prefix);
    }

    public static decrypt(cipher: Uint8Array, key: Uint8Array, assoc?: Uint8Array): Promise<Uint8Array>{
        return workerHandler.run(WorkerOperation.AESCipherSIVDeterministicDecrypt, cipher, key, assoc);
    }

    public static describe(): string{
        return "AES-SIV-N0-128/256";
    }

}


/**
 * One of the most widely used and generally good AES constructs.
    The security is prone to breaking by repeating nonce values if not coordinated by the participants.
 */
export class AESCipherGCM /*extends AESCipherGCMWorker*/{

    public static encrypt(plain: Uint8Array, key: Uint8Array, nonce?: Uint8Array, assoc?: Uint8Array, prefix?: Uint8Array): Promise<Uint8Array>{
        return workerHandler.run(WorkerOperation.AESCipherGCMEncrypt, plain, key, nonce, assoc, prefix);
    }

    public static decrypt(cipher: Uint8Array, key: Uint8Array, assoc?: Uint8Array): Promise<Uint8Array>{
        return workerHandler.run(WorkerOperation.AESCipherGCMDecrypt, cipher, key, assoc);
    }

    public static describe(): string{
        return "AES-GCM-128/256";
    }

}

/**
 * The simplest yet sometimes adequate and usable AES mode.
    NOTE: DO NOT USE THIS, PADDING PROBLEMS +-16 btes at the end of the encrypted data
*/
export class AESCipherCBC /*extends AESCipherCBCWorker*/{

    public static encrypt(plain: Uint8Array, key: Uint8Array, iv?: Uint8Array, prefix?: Uint8Array): Promise<Uint8Array>{
        return workerHandler.run(WorkerOperation.AESCipherCBCEncrypt, plain, key, iv, prefix);
    }

    public static decrypt(cipher: Uint8Array, key: Uint8Array): Promise<Uint8Array>{
        return workerHandler.run(WorkerOperation.AESCipherCBCDecrypt, cipher, key);
    }

    public static describe(): string{
        return "AES-CBC-128/256";
    }

}

