| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051 | // Output Feedbackimport { 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);  }}
 |