Skip to content

Commit

Permalink
Added multiple block processing to CBC and ECB.
Browse files Browse the repository at this point in the history
  • Loading branch information
ricmoo committed Aug 6, 2016
1 parent f387521 commit 28aabef
Show file tree
Hide file tree
Showing 9 changed files with 1,189 additions and 1,146 deletions.
13 changes: 11 additions & 2 deletions generate-tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,12 @@ def default(o, encoder=json.JSONEncoder()):

if mode == 'CBC':
iv = os.urandom(16)
plaintext = [ os.urandom(16) for x in xrange(0, test) ]

text_length = [None, 16, 16, 16, 32, 48, 64, 64, 64][test]
if test == 1:
plaintext = [ '' ]
else:
plaintext = [ os.urandom(text_length) for x in xrange(0, test) ]

kaes = KAES.new(key, KAES.MODE_CBC, IV = iv)
kaes2 = KAES.new(key, KAES.MODE_CBC, IV = iv)
Expand All @@ -74,7 +79,11 @@ def default(o, encoder=json.JSONEncoder()):
segment_size = test

elif mode == 'ECB':
plaintext = [ os.urandom(16) for x in xrange(0, test) ]
text_length = [None, 16, 16, 16, 32, 48, 64, 64, 64][test]
if test == 1:
plaintext = [ '' ]
else:
plaintext = [ os.urandom(text_length) for x in xrange(0, test) ]

kaes = KAES.new(key, KAES.MODE_ECB)
kaes2 = KAES.new(key, KAES.MODE_ECB)
Expand Down
78 changes: 59 additions & 19 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -379,11 +379,37 @@
}

ModeOfOperationECB.prototype.encrypt = function(plaintext) {
return this._aes.encrypt(plaintext);
if ((plaintext.length % 16) !== 0) {
throw new Error('invalid plaintext size (must be multiple of 16 bytes)');
}

var ciphertext = createBuffer(plaintext.length);
var block = createBuffer(16);

for (var i = 0; i < plaintext.length; i += 16) {
copyBuffer(plaintext, block, 0, i, i + 16);
block = this._aes.encrypt(block);
copyBuffer(block, ciphertext, i, 0, 16);
}

return ciphertext;
}

ModeOfOperationECB.prototype.decrypt = function(ciphertext, encoding) {
return this._aes.decrypt(ciphertext);
ModeOfOperationECB.prototype.decrypt = function(ciphertext) {
if ((ciphertext.length % 16) !== 0) {
throw new Error('invalid ciphertext size (must be multiple of 16 bytes)');
}

var plaintext = createBuffer(ciphertext.length);
var block = createBuffer(16);

for (var i = 0; i < ciphertext.length; i += 16) {
copyBuffer(ciphertext, block, 0, i, i + 16);
block = this._aes.decrypt(block);
copyBuffer(block, plaintext, i, 0, 16);
}

return plaintext;
}


Expand Down Expand Up @@ -411,31 +437,45 @@
}

ModeOfOperationCBC.prototype.encrypt = function(plaintext) {
if (plaintext.length != 16) {
throw new Error('invalid plaintext size (must be 16 bytes)');
if ((plaintext.length % 16) !== 0) {
throw new Error('invalid plaintext size (must be multiple of 16 bytes)');
}

var precipherblock = createBuffer(plaintext);
for (var i = 0; i < 16; i++) {
precipherblock[i] ^= this._lastCipherblock[i];
}
var ciphertext = createBuffer(plaintext.length);
var block = createBuffer(16);

for (var i = 0; i < plaintext.length; i += 16) {
copyBuffer(plaintext, block, 0, i, i + 16);

for (var j = 0; j < 16; j++) {
block[j] ^= this._lastCipherblock[j];
}

this._lastCipherblock = this._aes.encrypt(precipherblock);
this._lastCipherblock = this._aes.encrypt(block);
copyBuffer(this._lastCipherblock, ciphertext, i, 0, 16);
}

return this._lastCipherblock;
return ciphertext;
}

ModeOfOperationCBC.prototype.decrypt = function(ciphertext) {
if (ciphertext.length != 16) {
throw new Error('invalid ciphertext size (must be 16 bytes)');
if ((ciphertext.length % 16) !== 0) {
throw new Error('invalid ciphertext size (must be multiple of 16 bytes)');
}

var plaintext = this._aes.decrypt(ciphertext);
for (var i = 0; i < 16; i++) {
plaintext[i] ^= this._lastCipherblock[i];
}
var plaintext = createBuffer(ciphertext.length);
var block = createBuffer(16);

for (var i = 0; i < ciphertext.length; i += 16) {
copyBuffer(ciphertext, block, 0, i, i + 16);
block = this._aes.decrypt(block);

copyBuffer(ciphertext, this._lastCipherblock);
for (var j = 0; j < 16; j++) {
plaintext[i + j] = block[j] ^ this._lastCipherblock[j];
}

copyBuffer(ciphertext, this._lastCipherblock, 0, i, i + 16);
}

return plaintext;
}
Expand Down Expand Up @@ -647,7 +687,7 @@
ModeOfOperationCTR.prototype.decrypt = ModeOfOperationCTR.prototype.encrypt;


// The bsic modes of operation as a map
// The basic modes of operation as a map
var ModeOfOperation = {
ecb: ModeOfOperationECB,
cbc: ModeOfOperationCBC,
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "aes-js",
"version": "2.0.0",
"version": "2.1.0",
"bugs": {
"url": "http://github.com/ricmoo/aes-js/issues",
"email": "[email protected]"
Expand All @@ -11,7 +11,7 @@
},
"main": "index.js",
"scripts": {
"test": "node test/test-aes.js && node test/test-counter.js && node test/test-buffer.js && node test/test-errors.js"
"test": "./node_modules/.bin/nodeunit test/index.js"
},
"repository": {
"type": "git",
Expand Down
10 changes: 10 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

function populateTests(tests) {
for (var key in tests) {
module.exports[key] = tests[key];
}
}
populateTests(require('./test-aes.js'));
populateTests(require('./test-counter.js'));
populateTests(require('./test-buffer.js'));
populateTests(require('./test-errors.js'));
10 changes: 5 additions & 5 deletions test/test-aes.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,12 @@ function makeTest(options) {
var testVectors = require('./test-vectors.json');

var Tests = {};

var counts = {}
for (var i = 0; i < testVectors.length; i++) {
var test = testVectors[i];
name = 'test-' + test.modeOfOperation + '-' + test.key.length;
if (!Tests[name]) { Tests[name] = {}; }
Tests[name]['test-' + Object.keys(Tests[name]).length] = makeTest(test);
name = test.modeOfOperation + '-' + test.key.length;
counts[name] = (counts[name] || 0) + 1;
Tests['test-' + name + '-' + counts[name]] = makeTest(test);
}

nodeunit.reporters.default.run(Tests);
module.exports = Tests;
24 changes: 11 additions & 13 deletions test/test-buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,18 @@ function buffersEqual(a, b) {
return true;
}

nodeunit.reporters.default.run({
"test-buffer": {
"slowCreate": function(test) {
//var result = new AES(testArray).key;
var result = slowCreateBuffer(testArray);
test.ok(buffersEqual(testArray, result), 'bufferCreate failed to match input array');
module.exports = {
"test-slowCreate": function(test) {
//var result = new AES(testArray).key;
var result = slowCreateBuffer(testArray);
test.ok(buffersEqual(testArray, result), 'bufferCreate failed to match input array');

result = slowCreateBuffer(testBuffer);
test.ok(buffersEqual(testBuffer, result), 'bufferCreate failed to match input array');
result = slowCreateBuffer(testBuffer);
test.ok(buffersEqual(testBuffer, result), 'bufferCreate failed to match input array');

result = slowCreateBuffer(new WeirdBuffer(testArray));
test.ok(buffersEqual(testBuffer, result), 'bufferCreate failed to match input array');
result = slowCreateBuffer(new WeirdBuffer(testArray));
test.ok(buffersEqual(testBuffer, result), 'bufferCreate failed to match input array');

test.done();
},
test.done();
},
});
};
40 changes: 12 additions & 28 deletions test/test-counter.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,33 +57,17 @@ function makeTest (options) {
};
}

var Tests = {
'test-counter-nullish': {
'test-null': makeTest({nullish: null, incrementResult: "00000000000000000000000000000002"}),
'test-undefined': makeTest({nullish: undefined, incrementResult: "00000000000000000000000000000002"}),
},
'test-counter-number': {
'test-0': makeTest({number: 0, incrementResult: "00000000000000000000000000000001"}),
'test-1': makeTest({number: 1, incrementResult: "00000000000000000000000000000002"}),
'test-254': makeTest({number: 254, incrementResult: "000000000000000000000000000000ff"}),
'test-255': makeTest({number: 255, incrementResult: "00000000000000000000000000000100"}),
'test-256': makeTest({number: 256, incrementResult: "00000000000000000000000000000101"}),
},
'test-counter-bytes': {
'test-0000': makeTest({bytes: "00000000000000000000000000000000", incrementResult: "00000000000000000000000000000001"}),
'test-00ff': makeTest({bytes: "000000000000000000000000000000ff", incrementResult: "00000000000000000000000000000100"}),
'test-ffff': makeTest({bytes: "ffffffffffffffffffffffffffffffff", incrementResult: "00000000000000000000000000000000"}),
'test-dead': makeTest({bytes: "deadbeefdeadbeefdeadbeefdeadbeef", incrementResult: "deadbeefdeadbeefdeadbeefdeadbef0"}),
},
module.exports = {
'test-counter-nullish-null': makeTest({nullish: null, incrementResult: "00000000000000000000000000000002"}),
'test-counter-nullish-undefined': makeTest({nullish: undefined, incrementResult: "00000000000000000000000000000002"}),
'test-counter-number-0': makeTest({number: 0, incrementResult: "00000000000000000000000000000001"}),
'test-counter-number-1': makeTest({number: 1, incrementResult: "00000000000000000000000000000002"}),
'test-counter-number-254': makeTest({number: 254, incrementResult: "000000000000000000000000000000ff"}),
'test-counter-number-255': makeTest({number: 255, incrementResult: "00000000000000000000000000000100"}),
'test-counter-number-256': makeTest({number: 256, incrementResult: "00000000000000000000000000000101"}),
'test-counter-bytes-0000': makeTest({bytes: "00000000000000000000000000000000", incrementResult: "00000000000000000000000000000001"}),
'test-counter-bytes-00ff': makeTest({bytes: "000000000000000000000000000000ff", incrementResult: "00000000000000000000000000000100"}),
'test-counter-bytes-ffff': makeTest({bytes: "ffffffffffffffffffffffffffffffff", incrementResult: "00000000000000000000000000000000"}),
'test-counter-bytes-dead': makeTest({bytes: "deadbeefdeadbeefdeadbeefdeadbeef", incrementResult: "deadbeefdeadbeefdeadbeefdeadbef0"}),
};

/*
for (var i = 0; i < testVectors.length; i++) {
var test = testVectors[i];
name = 'test-' + test.modeOfOperation + '-' + test.key.length;
if (!Tests[name]) { Tests[name] = {}; }
Tests[name]['test-' + Object.keys(Tests[name]).length] = makeTest(test);
}
*/
nodeunit.reporters.default.run(Tests);

Loading

0 comments on commit 28aabef

Please sign in to comment.