rc4.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /*
  2. CryptoJS v3.1.2
  3. code.google.com/p/crypto-js
  4. (c) 2009-2013 by Jeff Mott. All rights reserved.
  5. code.google.com/p/crypto-js/wiki/License
  6. */
  7. (function () {
  8. // Shortcuts
  9. var C = CryptoJS;
  10. var C_lib = C.lib;
  11. var StreamCipher = C_lib.StreamCipher;
  12. var C_algo = C.algo;
  13. /**
  14. * RC4 stream cipher algorithm.
  15. */
  16. var RC4 = C_algo.RC4 = StreamCipher.extend({
  17. _doReset: function () {
  18. // Shortcuts
  19. var key = this._key;
  20. var keyWords = key.words;
  21. var keySigBytes = key.sigBytes;
  22. // Init sbox
  23. var S = this._S = [];
  24. for (var i = 0; i < 256; i++) {
  25. S[i] = i;
  26. }
  27. // Key setup
  28. for (var i = 0, j = 0; i < 256; i++) {
  29. var keyByteIndex = i % keySigBytes;
  30. var keyByte = (keyWords[keyByteIndex >>> 2] >>> (24 - (keyByteIndex % 4) * 8)) & 0xff;
  31. j = (j + S[i] + keyByte) % 256;
  32. // Swap
  33. var t = S[i];
  34. S[i] = S[j];
  35. S[j] = t;
  36. }
  37. // Counters
  38. this._i = this._j = 0;
  39. },
  40. _doProcessBlock: function (M, offset) {
  41. M[offset] ^= generateKeystreamWord.call(this);
  42. },
  43. keySize: 256/32,
  44. ivSize: 0
  45. });
  46. function generateKeystreamWord() {
  47. // Shortcuts
  48. var S = this._S;
  49. var i = this._i;
  50. var j = this._j;
  51. // Generate keystream word
  52. var keystreamWord = 0;
  53. for (var n = 0; n < 4; n++) {
  54. i = (i + 1) % 256;
  55. j = (j + S[i]) % 256;
  56. // Swap
  57. var t = S[i];
  58. S[i] = S[j];
  59. S[j] = t;
  60. keystreamWord |= S[(S[i] + S[j]) % 256] << (24 - n * 8);
  61. }
  62. // Update counters
  63. this._i = i;
  64. this._j = j;
  65. return keystreamWord;
  66. }
  67. /**
  68. * Shortcut functions to the cipher's object interface.
  69. *
  70. * @example
  71. *
  72. * var ciphertext = CryptoJS.RC4.encrypt(message, key, cfg);
  73. * var plaintext = CryptoJS.RC4.decrypt(ciphertext, key, cfg);
  74. */
  75. C.RC4 = StreamCipher._createHelper(RC4);
  76. /**
  77. * Modified RC4 stream cipher algorithm.
  78. */
  79. var RC4Drop = C_algo.RC4Drop = RC4.extend({
  80. /**
  81. * Configuration options.
  82. *
  83. * @property {number} drop The number of keystream words to drop. Default 192
  84. */
  85. cfg: RC4.cfg.extend({
  86. drop: 192
  87. }),
  88. _doReset: function () {
  89. RC4._doReset.call(this);
  90. // Drop
  91. for (var i = this.cfg.drop; i > 0; i--) {
  92. generateKeystreamWord.call(this);
  93. }
  94. }
  95. });
  96. /**
  97. * Shortcut functions to the cipher's object interface.
  98. *
  99. * @example
  100. *
  101. * var ciphertext = CryptoJS.RC4Drop.encrypt(message, key, cfg);
  102. * var plaintext = CryptoJS.RC4Drop.decrypt(ciphertext, key, cfg);
  103. */
  104. C.RC4Drop = StreamCipher._createHelper(RC4Drop);
  105. }());