des.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  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. var value = buffer.length - off;
  59. for (var i = off; i < buffer.length; i++)
  60. buffer[i] = value;
  61. return true;
  62. };
  63. DES.prototype._unpad = function _unpad(buffer) {
  64. var pad = buffer[buffer.length - 1];
  65. for (var i = buffer.length - pad; i < buffer.length; i++)
  66. assert.equal(buffer[i], pad);
  67. return buffer.slice(0, buffer.length - pad);
  68. };
  69. DES.prototype._encrypt = function _encrypt(state, lStart, rStart, out, off) {
  70. var l = lStart;
  71. var r = rStart;
  72. // Apply f() x16 times
  73. for (var i = 0; i < state.keys.length; i += 2) {
  74. var keyL = state.keys[i];
  75. var keyR = state.keys[i + 1];
  76. // f(r, k)
  77. utils.expand(r, state.tmp, 0);
  78. keyL ^= state.tmp[0];
  79. keyR ^= state.tmp[1];
  80. var s = utils.substitute(keyL, keyR);
  81. var f = utils.permute(s);
  82. var t = r;
  83. r = (l ^ f) >>> 0;
  84. l = t;
  85. }
  86. // Reverse Initial Permutation
  87. utils.rip(r, l, out, off);
  88. };
  89. DES.prototype._decrypt = function _decrypt(state, lStart, rStart, out, off) {
  90. var l = rStart;
  91. var r = lStart;
  92. // Apply f() x16 times
  93. for (var i = state.keys.length - 2; i >= 0; i -= 2) {
  94. var keyL = state.keys[i];
  95. var keyR = state.keys[i + 1];
  96. // f(r, k)
  97. utils.expand(l, state.tmp, 0);
  98. keyL ^= state.tmp[0];
  99. keyR ^= state.tmp[1];
  100. var s = utils.substitute(keyL, keyR);
  101. var f = utils.permute(s);
  102. var t = l;
  103. l = (r ^ f) >>> 0;
  104. r = t;
  105. }
  106. // Reverse Initial Permutation
  107. utils.rip(l, r, out, off);
  108. };