@stablelib/aes
Advanced tools
Comparing version 1.0.1 to 2.0.0
// Copyright (C) 2016 Dmitry Chestnykh | ||
// MIT License. See LICENSE file for details. | ||
import { describe, expect, it } from 'vitest'; | ||
import { AES } from "./aes"; | ||
@@ -5,0 +5,0 @@ import { encode, decode } from "@stablelib/hex"; |
@@ -18,3 +18,3 @@ // Copyright (C) 2016 Dmitry Chestnykh | ||
import { BlockCipher } from "@stablelib/blockcipher"; | ||
import type { BlockCipher } from "@stablelib/blockcipher"; | ||
import { wipe } from "@stablelib/wipe"; | ||
@@ -21,0 +21,0 @@ import { readUint32BE, writeUint32BE } from "@stablelib/binary"; |
@@ -1,14 +0,12 @@ | ||
"use strict"; | ||
// Copyright (C) 2016 Dmitry Chestnykh | ||
// MIT License. See LICENSE file for details. | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var aes_1 = require("./aes"); | ||
var benchmark_1 = require("@stablelib/benchmark"); | ||
var key = benchmark_1.byteSeq(32); | ||
var cipher = new aes_1.AES(key); | ||
var src = benchmark_1.byteSeq(16); | ||
var dst = new Uint8Array(16); | ||
benchmark_1.report("AES-256 init", benchmark_1.benchmark(function () { return new aes_1.AES(key); })); | ||
benchmark_1.report("AES-256 encrypt", benchmark_1.benchmark(function () { return cipher.encryptBlock(src, dst); }, src.length)); | ||
benchmark_1.report("AES-256 decrypt", benchmark_1.benchmark(function () { return cipher.decryptBlock(src, dst); }, src.length)); | ||
import { AES } from "./aes"; | ||
import { benchmark, report, byteSeq } from "@stablelib/benchmark"; | ||
const key = byteSeq(32); | ||
const cipher = new AES(key); | ||
const src = byteSeq(16); | ||
const dst = new Uint8Array(16); | ||
report("AES-256 init", benchmark(() => new AES(key))); | ||
report("AES-256 encrypt", benchmark(() => cipher.encryptBlock(src, dst), src.length)); | ||
report("AES-256 decrypt", benchmark(() => cipher.decryptBlock(src, dst), src.length)); | ||
//# sourceMappingURL=aes.bench.js.map |
/** | ||
* Package aes implements AES block cipher. | ||
*/ | ||
import { BlockCipher } from "@stablelib/blockcipher"; | ||
import type { BlockCipher } from "@stablelib/blockcipher"; | ||
/** | ||
@@ -6,0 +6,0 @@ * AES block cipher. |
153
lib/aes.js
@@ -1,9 +0,7 @@ | ||
"use strict"; | ||
// Copyright (C) 2016 Dmitry Chestnykh | ||
// MIT License. See LICENSE file for details. | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var wipe_1 = require("@stablelib/wipe"); | ||
var binary_1 = require("@stablelib/binary"); | ||
import { wipe } from "@stablelib/wipe"; | ||
import { readUint32BE, writeUint32BE } from "@stablelib/binary"; | ||
// Powers of x mod poly in GF(2). | ||
var POWX = new Uint8Array([ | ||
const POWX = new Uint8Array([ | ||
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, | ||
@@ -13,3 +11,3 @@ 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f | ||
// FIPS-197 Figure 7. S-box substitution values in hexadecimal format. | ||
var SBOX0 = new Uint8Array([ | ||
const SBOX0 = new Uint8Array([ | ||
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, | ||
@@ -33,3 +31,3 @@ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, | ||
// FIPS-197 Figure 14. Inverse S-box substitution values in hexadecimal format. | ||
var SBOX1 = new Uint8Array([ | ||
const SBOX1 = new Uint8Array([ | ||
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, | ||
@@ -54,13 +52,13 @@ 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, | ||
// Will be computed by initialize() when the first AES instance is created. | ||
var isInitialized = false; | ||
var Te0, Te1, Te2, Te3; | ||
var Td0, Td1, Td2, Td3; | ||
let isInitialized = false; | ||
let Te0, Te1, Te2, Te3; | ||
let Td0, Td1, Td2, Td3; | ||
// Initialize generates encryption and decryption tables. | ||
function initialize() { | ||
var poly = (1 << 8) | (1 << 4) | (1 << 3) | (1 << 1) | (1 << 0); | ||
const poly = (1 << 8) | (1 << 4) | (1 << 3) | (1 << 1) | (1 << 0); | ||
function mul(b, c) { | ||
var i = b; | ||
var j = c; | ||
var s = 0; | ||
for (var k = 1; k < 0x100 && j !== 0; k <<= 1) { | ||
let i = b; | ||
let j = c; | ||
let s = 0; | ||
for (let k = 1; k < 0x100 && j !== 0; k <<= 1) { | ||
// Invariant: k == 1<<n, i == b * x^n | ||
@@ -79,3 +77,3 @@ if ((j & k) !== 0) { | ||
} | ||
var rot = function (x) { return (x << 24) | (x >>> 8); }; | ||
const rot = (x) => (x << 24) | (x >>> 8); | ||
// Generate encryption tables. | ||
@@ -86,5 +84,5 @@ Te0 = new Uint32Array(256); | ||
Te3 = new Uint32Array(256); | ||
for (var i = 0; i < 256; i++) { | ||
var s = SBOX0[i]; | ||
var w = (mul(s, 2) << 24) | (s << 16) | (s << 8) | mul(s, 3); | ||
for (let i = 0; i < 256; i++) { | ||
const s = SBOX0[i]; | ||
let w = (mul(s, 2) << 24) | (s << 16) | (s << 8) | mul(s, 3); | ||
Te0[i] = w; | ||
@@ -104,5 +102,5 @@ w = rot(w); | ||
Td3 = new Uint32Array(256); | ||
for (var i = 0; i < 256; i++) { | ||
var s = SBOX1[i]; | ||
var w = (mul(s, 0xe) << 24) | (mul(s, 0x9) << 16) | | ||
for (let i = 0; i < 256; i++) { | ||
const s = SBOX1[i]; | ||
let w = (mul(s, 0xe) << 24) | (mul(s, 0x9) << 16) | | ||
(mul(s, 0xd) << 8) | mul(s, 0xb); | ||
@@ -129,3 +127,12 @@ Td0[i] = w; | ||
*/ | ||
var AES = /** @class */ (function () { | ||
export class AES { | ||
// AES block size in bytes. | ||
blockSize = 16; | ||
// Key byte length. | ||
_keyLen; | ||
// Expanded encryption key. | ||
_encKey; | ||
// Expanded decryption key. May be undefined if instance | ||
// was created "noDecryption" option set to true. | ||
_decKey; | ||
/** | ||
@@ -139,6 +146,3 @@ * Constructs AES with the given 16, 24 or 32-byte key | ||
*/ | ||
function AES(key, noDecryption) { | ||
if (noDecryption === void 0) { noDecryption = false; } | ||
// AES block size in bytes. | ||
this.blockSize = 16; | ||
constructor(key, noDecryption = false) { | ||
if (!isInitialized) { | ||
@@ -155,4 +159,3 @@ initialize(); | ||
*/ | ||
AES.prototype.setKey = function (key, noDecryption) { | ||
if (noDecryption === void 0) { noDecryption = false; } | ||
setKey(key, noDecryption = false) { | ||
if (key.length !== 16 && key.length !== 24 && key.length !== 32) { | ||
@@ -171,3 +174,3 @@ throw new Error("AES: wrong key size (must be 16, 24 or 32)"); | ||
if (this._decKey) { | ||
wipe_1.wipe(this._decKey); | ||
wipe(this._decKey); | ||
} | ||
@@ -182,15 +185,15 @@ } | ||
return this; | ||
}; | ||
} | ||
/** | ||
* Erases expanded keys from memory. | ||
*/ | ||
AES.prototype.clean = function () { | ||
clean() { | ||
if (this._encKey) { | ||
wipe_1.wipe(this._encKey); | ||
wipe(this._encKey); | ||
} | ||
if (this._decKey) { | ||
wipe_1.wipe(this._decKey); | ||
wipe(this._decKey); | ||
} | ||
return this; | ||
}; | ||
} | ||
/** | ||
@@ -204,3 +207,3 @@ * Encrypt 16-byte block src into 16-byte block dst. | ||
*/ | ||
AES.prototype.encryptBlock = function (src, dst) { | ||
encryptBlock(src, dst) { | ||
// Check block lengths. | ||
@@ -216,3 +219,3 @@ if (src.length < this.blockSize) { | ||
return this; | ||
}; | ||
} | ||
/** | ||
@@ -226,3 +229,3 @@ * Decrypt 16-byte block src into 16-byte block dst. | ||
*/ | ||
AES.prototype.decryptBlock = function (src, dst) { | ||
decryptBlock(src, dst) { | ||
// Check block lengths. | ||
@@ -243,6 +246,4 @@ if (src.length < this.blockSize) { | ||
return this; | ||
}; | ||
return AES; | ||
}()); | ||
exports.AES = AES; | ||
} | ||
} | ||
// Apply sbox0 to each byte in w. | ||
@@ -260,9 +261,9 @@ function subw(w) { | ||
function expandKey(key, encKey, decKey) { | ||
var nk = key.length / 4 | 0; | ||
var n = encKey.length; | ||
for (var i = 0; i < nk; i++) { | ||
encKey[i] = binary_1.readUint32BE(key, i * 4); | ||
const nk = key.length / 4 | 0; | ||
const n = encKey.length; | ||
for (let i = 0; i < nk; i++) { | ||
encKey[i] = readUint32BE(key, i * 4); | ||
} | ||
for (var i = nk; i < n; i++) { | ||
var t = encKey[i - 1]; | ||
for (let i = nk; i < n; i++) { | ||
let t = encKey[i - 1]; | ||
if (i % nk === 0) { | ||
@@ -280,6 +281,6 @@ t = subw(rotw(t)) ^ (POWX[i / nk - 1] << 24); | ||
// All sets but the first and last get the MixColumn transform applied. | ||
for (var i = 0; i < n; i += 4) { | ||
var ei = n - i - 4; | ||
for (var j = 0; j < 4; j++) { | ||
var x = encKey[ei + j]; | ||
for (let i = 0; i < n; i += 4) { | ||
const ei = n - i - 4; | ||
for (let j = 0; j < 4; j++) { | ||
let x = encKey[ei + j]; | ||
if (i > 0 && i + 4 < n) { | ||
@@ -295,6 +296,6 @@ x = Td0[SBOX0[(x >>> 24) & 0xff]] ^ Td1[SBOX0[(x >>> 16) & 0xff]] ^ | ||
function encryptBlock(xk, src, dst) { | ||
var s0 = binary_1.readUint32BE(src, 0); | ||
var s1 = binary_1.readUint32BE(src, 4); | ||
var s2 = binary_1.readUint32BE(src, 8); | ||
var s3 = binary_1.readUint32BE(src, 12); | ||
let s0 = readUint32BE(src, 0); | ||
let s1 = readUint32BE(src, 4); | ||
let s2 = readUint32BE(src, 8); | ||
let s3 = readUint32BE(src, 12); | ||
// First round just XORs input with key. | ||
@@ -305,8 +306,8 @@ s0 ^= xk[0]; | ||
s3 ^= xk[3]; | ||
var t0 = 0, t1 = 0, t2 = 0, t3 = 0; | ||
let t0 = 0, t1 = 0, t2 = 0, t3 = 0; | ||
// Middle rounds shuffle using tables. | ||
// Number of rounds is set by length of expanded key. | ||
var nr = xk.length / 4 - 2; // - 2: one above, one more below | ||
var k = 4; | ||
for (var r = 0; r < nr; r++) { | ||
const nr = xk.length / 4 - 2; // - 2: one above, one more below | ||
let k = 4; | ||
for (let r = 0; r < nr; r++) { | ||
t0 = xk[k + 0] ^ Te0[(s0 >>> 24) & 0xff] ^ Te1[(s1 >>> 16) & 0xff] ^ | ||
@@ -339,12 +340,12 @@ Te2[(s2 >>> 8) & 0xff] ^ Te3[s3 & 0xff]; | ||
s3 ^= xk[k + 3]; | ||
binary_1.writeUint32BE(s0, dst, 0); | ||
binary_1.writeUint32BE(s1, dst, 4); | ||
binary_1.writeUint32BE(s2, dst, 8); | ||
binary_1.writeUint32BE(s3, dst, 12); | ||
writeUint32BE(s0, dst, 0); | ||
writeUint32BE(s1, dst, 4); | ||
writeUint32BE(s2, dst, 8); | ||
writeUint32BE(s3, dst, 12); | ||
} | ||
function decryptBlock(xk, src, dst) { | ||
var s0 = binary_1.readUint32BE(src, 0); | ||
var s1 = binary_1.readUint32BE(src, 4); | ||
var s2 = binary_1.readUint32BE(src, 8); | ||
var s3 = binary_1.readUint32BE(src, 12); | ||
let s0 = readUint32BE(src, 0); | ||
let s1 = readUint32BE(src, 4); | ||
let s2 = readUint32BE(src, 8); | ||
let s3 = readUint32BE(src, 12); | ||
// First round just XORs input with key. | ||
@@ -355,8 +356,8 @@ s0 ^= xk[0]; | ||
s3 ^= xk[3]; | ||
var t0 = 0, t1 = 0, t2 = 0, t3 = 0; | ||
let t0 = 0, t1 = 0, t2 = 0, t3 = 0; | ||
// Middle rounds shuffle using tables. | ||
// Number of rounds is set by length of expanded key. | ||
var nr = xk.length / 4 - 2; // - 2: one above, one more below | ||
var k = 4; | ||
for (var r = 0; r < nr; r++) { | ||
const nr = xk.length / 4 - 2; // - 2: one above, one more below | ||
let k = 4; | ||
for (let r = 0; r < nr; r++) { | ||
t0 = xk[k + 0] ^ Td0[(s0 >>> 24) & 0xff] ^ Td1[(s3 >>> 16) & 0xff] ^ | ||
@@ -389,7 +390,7 @@ Td2[(s2 >>> 8) & 0xff] ^ Td3[s1 & 0xff]; | ||
s3 ^= xk[k + 3]; | ||
binary_1.writeUint32BE(s0, dst, 0); | ||
binary_1.writeUint32BE(s1, dst, 4); | ||
binary_1.writeUint32BE(s2, dst, 8); | ||
binary_1.writeUint32BE(s3, dst, 12); | ||
writeUint32BE(s0, dst, 0); | ||
writeUint32BE(s1, dst, 4); | ||
writeUint32BE(s2, dst, 8); | ||
writeUint32BE(s3, dst, 12); | ||
} | ||
//# sourceMappingURL=aes.js.map |
@@ -1,9 +0,8 @@ | ||
"use strict"; | ||
// Copyright (C) 2016 Dmitry Chestnykh | ||
// MIT License. See LICENSE file for details. | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var aes_1 = require("./aes"); | ||
var hex_1 = require("@stablelib/hex"); | ||
import { describe, expect, it } from 'vitest'; | ||
import { AES } from "./aes"; | ||
import { encode, decode } from "@stablelib/hex"; | ||
// TODO(dchest): add more AES test vectors. | ||
var testVectors = [ | ||
const testVectors = [ | ||
{ | ||
@@ -30,27 +29,27 @@ key: "2B7E151628AED2A6ABF7158809CF4F3C", | ||
]; | ||
describe("AES", function () { | ||
it("should not accept wrong key length", function () { | ||
expect(function () { return new aes_1.AES(new Uint8Array(10)); }).toThrowError(/^AES/); | ||
describe("AES", () => { | ||
it("should not accept wrong key length", () => { | ||
expect(() => new AES(new Uint8Array(10))).toThrowError(/^AES/); | ||
}); | ||
it("should not accept different key in setKey()", function () { | ||
var cipher = new aes_1.AES(new Uint8Array(32)); | ||
expect(function () { return cipher.setKey(new Uint8Array(16)); }).toThrowError(/^AES/); | ||
it("should not accept different key in setKey()", () => { | ||
const cipher = new AES(new Uint8Array(32)); | ||
expect(() => cipher.setKey(new Uint8Array(16))).toThrowError(/^AES/); | ||
}); | ||
}); | ||
describe("AES.encryptBlock", function () { | ||
it("should correctly encrypt block", function () { | ||
testVectors.forEach(function (v) { | ||
var cipher = new aes_1.AES(hex_1.decode(v.key)); | ||
var dst = new Uint8Array(16); | ||
cipher.encryptBlock(hex_1.decode(v.src), dst); | ||
expect(hex_1.encode(dst)).toBe(v.dst); | ||
describe("AES.encryptBlock", () => { | ||
it("should correctly encrypt block", () => { | ||
testVectors.forEach(v => { | ||
const cipher = new AES(decode(v.key)); | ||
const dst = new Uint8Array(16); | ||
cipher.encryptBlock(decode(v.src), dst); | ||
expect(encode(dst)).toBe(v.dst); | ||
}); | ||
}); | ||
it("should correctly encrypt many blocks with different keys", function () { | ||
var key = new Uint8Array(32); | ||
var block = new Uint8Array(16); | ||
var newKey = new Uint8Array(32); | ||
for (var i = 0; i < 100; i++) { | ||
var cipher = new aes_1.AES(key); | ||
for (var j = 0; j < 100; j++) { | ||
it("should correctly encrypt many blocks with different keys", () => { | ||
let key = new Uint8Array(32); | ||
let block = new Uint8Array(16); | ||
const newKey = new Uint8Array(32); | ||
for (let i = 0; i < 100; i++) { | ||
const cipher = new AES(key); | ||
for (let j = 0; j < 100; j++) { | ||
cipher.encryptBlock(block, block); | ||
@@ -62,21 +61,21 @@ } | ||
} | ||
expect(hex_1.encode(block)).toBe("3A6FD932F608835F1F56D9DC1FCECFA3"); | ||
expect(encode(block)).toBe("3A6FD932F608835F1F56D9DC1FCECFA3"); | ||
}); | ||
}); | ||
describe("AES.decryptBlock", function () { | ||
it("should correctly decrypt block", function () { | ||
testVectors.forEach(function (v) { | ||
var cipher = new aes_1.AES(hex_1.decode(v.key)); | ||
var src = new Uint8Array(16); | ||
cipher.decryptBlock(hex_1.decode(v.dst), src); | ||
expect(hex_1.encode(src)).toBe(v.src); | ||
describe("AES.decryptBlock", () => { | ||
it("should correctly decrypt block", () => { | ||
testVectors.forEach(v => { | ||
const cipher = new AES(decode(v.key)); | ||
const src = new Uint8Array(16); | ||
cipher.decryptBlock(decode(v.dst), src); | ||
expect(encode(src)).toBe(v.src); | ||
}); | ||
}); | ||
it("should correctly decrypt many blocks with different keys", function () { | ||
var key = new Uint8Array(32); | ||
var block = new Uint8Array(16); | ||
var newKey = new Uint8Array(32); | ||
for (var i = 0; i < 100; i++) { | ||
var cipher = new aes_1.AES(key); | ||
for (var j = 0; j < 100; j++) { | ||
it("should correctly decrypt many blocks with different keys", () => { | ||
let key = new Uint8Array(32); | ||
let block = new Uint8Array(16); | ||
const newKey = new Uint8Array(32); | ||
for (let i = 0; i < 100; i++) { | ||
const cipher = new AES(key); | ||
for (let j = 0; j < 100; j++) { | ||
cipher.decryptBlock(block, block); | ||
@@ -88,5 +87,5 @@ } | ||
} | ||
expect(hex_1.encode(block)).toBe("551EC0EA8EA69F1FC4EF95E6420AD4B6"); | ||
expect(encode(block)).toBe("551EC0EA8EA69F1FC4EF95E6420AD4B6"); | ||
}); | ||
}); | ||
//# sourceMappingURL=aes.test.js.map |
{ | ||
"name": "@stablelib/aes", | ||
"version": "1.0.1", | ||
"version": "2.0.0", | ||
"description": "AES block cipher (Advanced Encryption Standard)", | ||
"main": "./lib/aes.js", | ||
"type": "module", | ||
"typings": "./lib/aes.d.ts", | ||
@@ -18,15 +19,15 @@ "author": "Dmitry Chestnykh", | ||
"build": "tsc", | ||
"test": "jasmine JASMINE_CONFIG_PATH=../../configs/jasmine.json", | ||
"test": "vitest run", | ||
"bench": "node ./lib/aes.bench.js" | ||
}, | ||
"dependencies": { | ||
"@stablelib/binary": "^1.0.1", | ||
"@stablelib/blockcipher": "^1.0.1", | ||
"@stablelib/wipe": "^1.0.1" | ||
"@stablelib/binary": "^2.0.0", | ||
"@stablelib/blockcipher": "^2.0.0", | ||
"@stablelib/wipe": "^2.0.0" | ||
}, | ||
"devDependencies": { | ||
"@stablelib/benchmark": "^1.0.1", | ||
"@stablelib/hex": "^1.0.1" | ||
"@stablelib/benchmark": "^2.0.0", | ||
"@stablelib/hex": "^2.0.0" | ||
}, | ||
"gitHead": "03dadf27703120d54e6be8436525228ee1c4299b" | ||
"gitHead": "ecfe9109b3c05419fd3ffc16da6c8255b08ad64f" | ||
} |
{ | ||
"extends": "../../configs/tsconfig.json", | ||
"compilerOptions": { | ||
"target": "es5", | ||
"module": "commonjs", | ||
"strict": true, | ||
"noUnusedParameters": true, | ||
"noImplicitReturns": true, | ||
"noUnusedLocals": true, | ||
"removeComments": false, | ||
"preserveConstEnums": true, | ||
"moduleResolution": "node", | ||
"newLine": "LF", | ||
"sourceMap": true, | ||
"declaration": true, | ||
"outDir": "lib", | ||
"lib": [ | ||
"es5", | ||
"es2015.promise", | ||
"dom", | ||
"scripthost" | ||
] | ||
}, | ||
@@ -23,0 +6,0 @@ "exclude": [ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
16
Yes
69177
1016
+ Added@stablelib/binary@2.0.0(transitive)
+ Added@stablelib/blockcipher@2.0.0(transitive)
+ Added@stablelib/int@2.0.0(transitive)
+ Added@stablelib/wipe@2.0.0(transitive)
- Removed@stablelib/binary@1.0.1(transitive)
- Removed@stablelib/blockcipher@1.0.1(transitive)
- Removed@stablelib/int@1.0.1(transitive)
- Removed@stablelib/wipe@1.0.1(transitive)
Updated@stablelib/binary@^2.0.0
Updated@stablelib/wipe@^2.0.0