{"version":3,"file":"ctr.mjs","sources":["../src/ctr.ts"],"sourcesContent":["import { assertIv, type BlockCipher, type ModeComponent, type PresetComponent, type Transform } from '@jscrypto/core';\n\nexport const ctr: ModeComponent<'CTR'> = {\n  kind: 'mode',\n  name: 'CTR',\n  requiresPadding: false,\n  getIvSize: (cipher) => cipher.blockSize,\n  createEncryptor({ cipher, iv, options }) {\n    assertIv(cipher.blockSize, iv, 'CTR');\n    return createCtrTransform(cipher, iv, getMutableInput(options));\n  },\n  createDecryptor({ cipher, iv, options }) {\n    assertIv(cipher.blockSize, iv, 'CTR');\n    return createCtrTransform(cipher, iv, getMutableInput(options));\n  },\n};\n\nexport const ctrPreset: PresetComponent<'ctr'> = {\n  kind: 'preset',\n  name: 'ctr',\n  components() {\n    return [ctr];\n  },\n};\n\nfunction createCtrTransform(cipher: BlockCipher, iv: Uint8Array, mutableInput: boolean): Transform {\n  const counter = iv.slice();\n  let keystream: Uint8Array = new Uint8Array(cipher.blockSize);\n  let position = cipher.blockSize;\n\n  return {\n    process(input) {\n      const output = mutableInput ? input : new Uint8Array(input.length);\n      let offset = 0;\n\n      if (position === cipher.blockSize) {\n        for (; offset + cipher.blockSize <= input.length; offset += cipher.blockSize) {\n          encryptCounter(cipher, counter, keystream);\n          incrementCounter(counter);\n          for (let index = 0; index < cipher.blockSize; index++) {\n            output[offset + index] = input[offset + index] ^ keystream[index];\n          }\n        }\n      }\n\n      for (let i = offset; i < input.length; i++) {\n        if (position === cipher.blockSize) {\n          encryptCounter(cipher, counter, keystream);\n          incrementCounter(counter);\n          position = 0;\n        }\n\n        output[i] = input[i] ^ keystream[position];\n        position++;\n      }\n\n      return output;\n    },\n\n    finalize(input = new Uint8Array(0)) {\n      return input.length === 0 ? new Uint8Array(0) : this.process(input);\n    },\n  };\n}\n\nfunction encryptCounter(cipher: BlockCipher, counter: Uint8Array, keystream: Uint8Array): void {\n  if (cipher.encryptBlock) {\n    cipher.encryptBlock(counter, 0, keystream, 0);\n  } else {\n    cipher.encrypt(counter, keystream);\n  }\n}\n\nfunction incrementCounter(counter: Uint8Array): void {\n  for (let i = counter.length - 1; i >= 0; i--) {\n    counter[i] = (counter[i] + 1) & 0xff;\n    if (counter[i] !== 0) {\n      return;\n    }\n  }\n}\n\nfunction getMutableInput(options: unknown): boolean {\n  if (typeof options !== 'object' || options === null) {\n    return false;\n  }\n  return 'mutableInput' in options && options.mutableInput === true;\n}\n"],"names":[],"mappings":";;;;;;;AAEO,MAAM,GAAG,GAAyB;AACvC,IAAA,IAAI,EAAE,MAAM;AACZ,IAAA,IAAI,EAAE,KAAK;AACX,IAAA,eAAe,EAAE,KAAK;IACtB,SAAS,EAAE,CAAC,MAAM,KAAK,MAAM,CAAC,SAAS;AACvC,IAAA,eAAe,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,EAAA;QACrC,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,EAAE,KAAK,CAAC;QACrC,OAAO,kBAAkB,CAAC,MAAM,EAAE,EAAE,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;IACjE,CAAC;AACD,IAAA,eAAe,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,EAAA;QACrC,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,EAAE,KAAK,CAAC;QACrC,OAAO,kBAAkB,CAAC,MAAM,EAAE,EAAE,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;IACjE,CAAC;;AAGI,MAAM,SAAS,GAA2B;AAC/C,IAAA,IAAI,EAAE,QAAQ;AACd,IAAA,IAAI,EAAE,KAAK;IACX,UAAU,GAAA;QACR,OAAO,CAAC,GAAG,CAAC;IACd,CAAC;;AAGH,SAAS,kBAAkB,CAAC,MAAmB,EAAE,EAAc,EAAE,YAAqB,EAAA;AACpF,IAAA,MAAM,OAAO,GAAG,EAAE,CAAC,KAAK,EAAE;IAC1B,IAAI,SAAS,GAAe,IAAI,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC;AAC5D,IAAA,IAAI,QAAQ,GAAG,MAAM,CAAC,SAAS;IAE/B,OAAO;AACL,QAAA,OAAO,CAAC,KAAK,EAAA;AACX,YAAA,MAAM,MAAM,GAAG,YAAY,GAAG,KAAK,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC;YAClE,IAAI,MAAM,GAAG,CAAC;AAEd,YAAA,IAAI,QAAQ,KAAK,MAAM,CAAC,SAAS,EAAE;AACjC,gBAAA,OAAO,MAAM,GAAG,MAAM,CAAC,SAAS,IAAI,KAAK,CAAC,MAAM,EAAE,MAAM,IAAI,MAAM,CAAC,SAAS,EAAE;AAC5E,oBAAA,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC;oBAC1C,gBAAgB,CAAC,OAAO,CAAC;AACzB,oBAAA,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE;AACrD,wBAAA,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC;oBACnE;gBACF;YACF;AAEA,YAAA,KAAK,IAAI,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AAC1C,gBAAA,IAAI,QAAQ,KAAK,MAAM,CAAC,SAAS,EAAE;AACjC,oBAAA,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC;oBAC1C,gBAAgB,CAAC,OAAO,CAAC;oBACzB,QAAQ,GAAG,CAAC;gBACd;AAEA,gBAAA,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,QAAQ,CAAC;AAC1C,gBAAA,QAAQ,EAAE;YACZ;AAEA,YAAA,OAAO,MAAM;QACf,CAAC;AAED,QAAA,QAAQ,CAAC,KAAK,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,EAAA;YAChC,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;QACrE,CAAC;KACF;AACH;AAEA,SAAS,cAAc,CAAC,MAAmB,EAAE,OAAmB,EAAE,SAAqB,EAAA;AACrF,IAAA,IAAI,MAAM,CAAC,YAAY,EAAE;QACvB,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;IAC/C;SAAO;AACL,QAAA,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,SAAS,CAAC;IACpC;AACF;AAEA,SAAS,gBAAgB,CAAC,OAAmB,EAAA;AAC3C,IAAA,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;AAC5C,QAAA,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI;AACpC,QAAA,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE;YACpB;QACF;IACF;AACF;AAEA,SAAS,eAAe,CAAC,OAAgB,EAAA;IACvC,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE;AACnD,QAAA,OAAO,KAAK;IACd;IACA,OAAO,cAAc,IAAI,OAAO,IAAI,OAAO,CAAC,YAAY,KAAK,IAAI;AACnE;;;;"}