2352ae5e077941d56f3c2905631104fd38504f3f3f144a4be1d85ad597d58895e0b536b721f7b2279be5100ef7f70a7778390aa148f871080f6af581697ccd 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. 'use strict';
  2. var assert = require('minimalistic-assert');
  3. var inherits = require('inherits');
  4. var utils = require('./utils');
  5. var Cipher = require('./cipher');
  6. function DESState() {
  7. this.tmp = new Array(2);
  8. this.keys = null;
  9. }
  10. function DES(options) {
  11. Cipher.call(this, options);
  12. var state = new DESState();
  13. this._desState = state;
  14. this.deriveKeys(state, options.key);
  15. }
  16. inherits(DES, Cipher);
  17. module.exports = DES;
  18. DES.create = function create(options) {
  19. return new DES(options);
  20. };
  21. var shiftTable = [
  22. 1, 1, 2, 2, 2, 2, 2, 2,
  23. 1, 2, 2, 2, 2, 2, 2, 1
  24. ];
  25. DES.prototype.deriveKeys = function deriveKeys(state, key) {
  26. state.keys = new Array(16 * 2);
  27. assert.equal(key.length, this.blockSize, 'Invalid key length');
  28. var kL = utils.readUInt32BE(key, 0);
  29. var kR = utils.readUInt32BE(key, 4);
  30. utils.pc1(kL, kR, state.tmp, 0);
  31. kL = state.tmp[0];
  32. kR = state.tmp[1];
  33. for (var i = 0; i < state.keys.length; i += 2) {
  34. var shift = shiftTable[i >>> 1];
  35. kL = utils.r28shl(kL, shift);
  36. kR = utils.r28shl(kR, shift);
  37. utils.pc2(kL, kR, state.keys, i);
  38. }
  39. };
  40. DES.prototype._update = function _update(inp, inOff, out, outOff) {
  41. var state = this._desState;
  42. var l = utils.readUInt32BE(inp, inOff);
  43. var r = utils.readUInt32BE(inp, inOff + 4);
  44. // Initial Permutation
  45. utils.ip(l, r, state.tmp, 0);
  46. l = state.tmp[0];
  47. r = state.tmp[1];
  48. if (this.type === 'encrypt')
  49. this._encrypt(state, l, r, state.tmp, 0);
  50. else
  51. this._decrypt(state, l, r, state.tmp, 0);
  52. l = state.tmp[0];
  53. r = state.tmp[1];
  54. utils.writeUInt32BE(out, l, outOff);
  55. utils.writeUInt32BE(out, r, outOff + 4);
  56. };
  57. DES.prototype._pad = function _pad(buffer, off) {
  58. if (this.padding === false) {
  59. return false;
  60. }
  61. var value = buffer.length - off;
  62. for (var i = off; i < buffer.length; i++)
  63. buffer[i] = value;
  64. return true;
  65. };
  66. DES.prototype._unpad = function _unpad(buffer) {
  67. if (this.padding === false) {
  68. return buffer;
  69. }
  70. var pad = buffer[buffer.length - 1];
  71. for (var i = buffer.length - pad; i < buffer.length; i++)
  72. assert.equal(buffer[i], pad);
  73. return buffer.slice(0, buffer.length - pad);
  74. };
  75. DES.prototype._encrypt = function _encrypt(state, lStart, rStart, out, off) {
  76. var l = lStart;
  77. var r = rStart;
  78. // Apply f() x16 times
  79. for (var i = 0; i < state.keys.length; i += 2) {
  80. var keyL = state.keys[i];
  81. var keyR = state.keys[i + 1];
  82. // f(r, k)
  83. utils.expand(r, state.tmp, 0);
  84. keyL ^= state.tmp[0];
  85. keyR ^= state.tmp[1];
  86. var s = utils.substitute(keyL, keyR);
  87. var f = utils.permute(s);
  88. var t = r;
  89. r = (l ^ f) >>> 0;
  90. l = t;
  91. }
  92. // Reverse Initial Permutation
  93. utils.rip(r, l, out, off);
  94. };
  95. DES.prototype._decrypt = function _decrypt(state, lStart, rStart, out, off) {
  96. var l = rStart;
  97. var r = lStart;
  98. // Apply f() x16 times
  99. for (var i = state.keys.length - 2; i >= 0; i -= 2) {
  100. var keyL = state.keys[i];
  101. var keyR = state.keys[i + 1];
  102. // f(r, k)
  103. utils.expand(l, state.tmp, 0);
  104. keyL ^= state.tmp[0];
  105. keyR ^= state.tmp[1];
  106. var s = utils.substitute(keyL, keyR);
  107. var f = utils.permute(s);
  108. var t = l;
  109. l = (r ^ f) >>> 0;
  110. r = t;
  111. }
  112. // Reverse Initial Permutation
  113. utils.rip(l, r, out, off);
  114. };