123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- 'use strict';
-
- var assert = require('minimalistic-assert');
- var inherits = require('inherits');
-
- var des = require('../des');
- var utils = des.utils;
- var Cipher = des.Cipher;
-
- function DESState() {
- this.tmp = new Array(2);
- this.keys = null;
- }
-
- function DES(options) {
- Cipher.call(this, options);
-
- var state = new DESState();
- this._desState = state;
-
- this.deriveKeys(state, options.key);
- }
- inherits(DES, Cipher);
- module.exports = DES;
-
- DES.create = function create(options) {
- return new DES(options);
- };
-
- var shiftTable = [
- 1, 1, 2, 2, 2, 2, 2, 2,
- 1, 2, 2, 2, 2, 2, 2, 1
- ];
-
- DES.prototype.deriveKeys = function deriveKeys(state, key) {
- state.keys = new Array(16 * 2);
-
- assert.equal(key.length, this.blockSize, 'Invalid key length');
-
- var kL = utils.readUInt32BE(key, 0);
- var kR = utils.readUInt32BE(key, 4);
-
- utils.pc1(kL, kR, state.tmp, 0);
- kL = state.tmp[0];
- kR = state.tmp[1];
- for (var i = 0; i < state.keys.length; i += 2) {
- var shift = shiftTable[i >>> 1];
- kL = utils.r28shl(kL, shift);
- kR = utils.r28shl(kR, shift);
- utils.pc2(kL, kR, state.keys, i);
- }
- };
-
- DES.prototype._update = function _update(inp, inOff, out, outOff) {
- var state = this._desState;
-
- var l = utils.readUInt32BE(inp, inOff);
- var r = utils.readUInt32BE(inp, inOff + 4);
-
- // Initial Permutation
- utils.ip(l, r, state.tmp, 0);
- l = state.tmp[0];
- r = state.tmp[1];
-
- if (this.type === 'encrypt')
- this._encrypt(state, l, r, state.tmp, 0);
- else
- this._decrypt(state, l, r, state.tmp, 0);
-
- l = state.tmp[0];
- r = state.tmp[1];
-
- utils.writeUInt32BE(out, l, outOff);
- utils.writeUInt32BE(out, r, outOff + 4);
- };
-
- DES.prototype._pad = function _pad(buffer, off) {
- var value = buffer.length - off;
- for (var i = off; i < buffer.length; i++)
- buffer[i] = value;
-
- return true;
- };
-
- DES.prototype._unpad = function _unpad(buffer) {
- var pad = buffer[buffer.length - 1];
- for (var i = buffer.length - pad; i < buffer.length; i++)
- assert.equal(buffer[i], pad);
-
- return buffer.slice(0, buffer.length - pad);
- };
-
- DES.prototype._encrypt = function _encrypt(state, lStart, rStart, out, off) {
- var l = lStart;
- var r = rStart;
-
- // Apply f() x16 times
- for (var i = 0; i < state.keys.length; i += 2) {
- var keyL = state.keys[i];
- var keyR = state.keys[i + 1];
-
- // f(r, k)
- utils.expand(r, state.tmp, 0);
-
- keyL ^= state.tmp[0];
- keyR ^= state.tmp[1];
- var s = utils.substitute(keyL, keyR);
- var f = utils.permute(s);
-
- var t = r;
- r = (l ^ f) >>> 0;
- l = t;
- }
-
- // Reverse Initial Permutation
- utils.rip(r, l, out, off);
- };
-
- DES.prototype._decrypt = function _decrypt(state, lStart, rStart, out, off) {
- var l = rStart;
- var r = lStart;
-
- // Apply f() x16 times
- for (var i = state.keys.length - 2; i >= 0; i -= 2) {
- var keyL = state.keys[i];
- var keyR = state.keys[i + 1];
-
- // f(r, k)
- utils.expand(l, state.tmp, 0);
-
- keyL ^= state.tmp[0];
- keyR ^= state.tmp[1];
- var s = utils.substitute(keyL, keyR);
- var f = utils.permute(s);
-
- var t = l;
- l = (r ^ f) >>> 0;
- r = t;
- }
-
- // Reverse Initial Permutation
- utils.rip(l, r, out, off);
- };
|