123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051 |
- // Output Feedback
- import { ModeOfOperation } from "./mode.js";
- export class OFB extends ModeOfOperation {
- #iv: Uint8Array;
- #lastPrecipher: Uint8Array;
- #lastPrecipherIndex: number;
- constructor(key: Uint8Array, iv?: Uint8Array) {
- super("OFB", key, OFB);
- if (iv) {
- if (iv.length % 16) {
- throw new TypeError("invalid iv size (must be 16 bytes)");
- }
- this.#iv = new Uint8Array(iv);
- } else {
- this.#iv = new Uint8Array(16);
- }
- this.#lastPrecipher = this.iv;
- this.#lastPrecipherIndex = 16;
- }
- get iv(): Uint8Array { return new Uint8Array(this.#iv); }
- encrypt(plaintext: Uint8Array): Uint8Array {
- if (plaintext.length % 16) {
- throw new TypeError("invalid plaintext size (must be multiple of 16 bytes)");
- }
- const ciphertext = new Uint8Array(plaintext);
- for (let i = 0; i < ciphertext.length; i++) {
- if (this.#lastPrecipherIndex === 16) {
- this.#lastPrecipher = this.aes.encrypt(this.#lastPrecipher);
- this.#lastPrecipherIndex = 0;
- }
- ciphertext[i] ^= this.#lastPrecipher[this.#lastPrecipherIndex++];
- }
- return ciphertext;
- }
- decrypt(ciphertext: Uint8Array): Uint8Array {
- if (ciphertext.length % 16) {
- throw new TypeError("invalid ciphertext size (must be multiple of 16 bytes)");
- }
- return this.encrypt(ciphertext);
- }
- }
|