mode-cfb.js 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. import {
  2. BlockCipherMode,
  3. } from './cipher-core.js';
  4. function generateKeystreamAndEncrypt(words, offset, blockSize, cipher) {
  5. const _words = words;
  6. let keystream;
  7. // Shortcut
  8. const iv = this._iv;
  9. // Generate keystream
  10. if (iv) {
  11. keystream = iv.slice(0);
  12. // Remove IV for subsequent blocks
  13. this._iv = undefined;
  14. } else {
  15. keystream = this._prevBlock;
  16. }
  17. cipher.encryptBlock(keystream, 0);
  18. // Encrypt
  19. for (let i = 0; i < blockSize; i += 1) {
  20. _words[offset + i] ^= keystream[i];
  21. }
  22. }
  23. /**
  24. * Cipher Feedback block mode.
  25. */
  26. export class CFB extends BlockCipherMode {
  27. }
  28. CFB.Encryptor = class extends CFB {
  29. processBlock(words, offset) {
  30. // Shortcuts
  31. const cipher = this._cipher;
  32. const { blockSize } = cipher;
  33. generateKeystreamAndEncrypt.call(this, words, offset, blockSize, cipher);
  34. // Remember this block to use with next block
  35. this._prevBlock = words.slice(offset, offset + blockSize);
  36. }
  37. };
  38. CFB.Decryptor = class extends CFB {
  39. processBlock(words, offset) {
  40. // Shortcuts
  41. const cipher = this._cipher;
  42. const { blockSize } = cipher;
  43. // Remember this block to use with next block
  44. const thisBlock = words.slice(offset, offset + blockSize);
  45. generateKeystreamAndEncrypt.call(this, words, offset, blockSize, cipher);
  46. // This block becomes the previous block
  47. this._prevBlock = thisBlock;
  48. }
  49. };