diff --git a/.gitignore b/.gitignore
index b947077..c2658d7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1 @@
node_modules/
-dist/
diff --git a/dist/aes-cmac.d.ts b/dist/aes-cmac.d.ts
new file mode 100644
index 0000000..7399b43
--- /dev/null
+++ b/dist/aes-cmac.d.ts
@@ -0,0 +1,4 @@
+///
+export declare const generateSubkeys: (key: Buffer) => [Buffer, Buffer];
+export declare const generateAesCmac: (key: Buffer, message: Buffer) => Buffer;
+export declare const verifyAesCmac: (aesCmac: Buffer, key: Buffer, message: Buffer) => boolean;
diff --git a/dist/aes-cmac.js b/dist/aes-cmac.js
new file mode 100644
index 0000000..1046c87
--- /dev/null
+++ b/dist/aes-cmac.js
@@ -0,0 +1,73 @@
+"use strict";
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.verifyAesCmac = exports.generateAesCmac = exports.generateSubkeys = void 0;
+const crypto_1 = __importDefault(require("crypto"));
+const buffer_utils_1 = require("./buffer-utils");
+const ZERO = Buffer.from("00000000000000000000000000000000", "hex");
+const RB = Buffer.from("00000000000000000000000000000087", "hex");
+const BLOCK_SIZE = 16;
+const Ciphers = {
+ aes128: 16,
+ aes192: 24,
+ aes256: 32,
+};
+const aes = (key, message) => {
+ const algorithm = Object.keys(Ciphers).find((cipherKey) => {
+ return (Ciphers[cipherKey] === key.length);
+ });
+ if (!algorithm) {
+ throw new Error("Keys must be 128, 192, or 256 bits in length.");
+ }
+ const cipher = crypto_1.default.createCipheriv(algorithm, key, ZERO);
+ const result = cipher.update(message);
+ cipher.final();
+ return result;
+};
+const generateSubkeys = (key) => {
+ const l = aes(key, ZERO);
+ const k1 = l[0] & 0x80 ? buffer_utils_1.xor(buffer_utils_1.bitShiftLeft(l), RB) : buffer_utils_1.bitShiftLeft(l);
+ const k2 = k1[0] & 0x80 ? buffer_utils_1.xor(buffer_utils_1.bitShiftLeft(k1), RB) : buffer_utils_1.bitShiftLeft(k1);
+ return [k1, k2];
+};
+exports.generateSubkeys = generateSubkeys;
+const generateAesCmac = (key, message) => {
+ const [k1, k2] = exports.generateSubkeys(key);
+ const blockCount = Math.ceil(message.length / BLOCK_SIZE);
+ const lastBlockCompleteFlag = blockCount === 0 ? false : message.length % BLOCK_SIZE === 0;
+ const lastBlockIndex = blockCount === 0 ? 0 : blockCount - 1;
+ const lastBlock = lastBlockCompleteFlag
+ ? buffer_utils_1.xor(getMessageBlock(message, lastBlockIndex), k1)
+ : buffer_utils_1.xor(getPaddedMessageBlock(message, lastBlockIndex), k2);
+ let x = Buffer.from("00000000000000000000000000000000", "hex");
+ let y;
+ for (let index = 0; index < lastBlockIndex; index++) {
+ y = buffer_utils_1.xor(x, getMessageBlock(message, index));
+ x = aes(key, y);
+ }
+ return aes(key, buffer_utils_1.xor(lastBlock, x));
+};
+exports.generateAesCmac = generateAesCmac;
+const verifyAesCmac = (aesCmac, key, message) => {
+ const expected = exports.generateAesCmac(key, message);
+ return aesCmac.equals(expected);
+};
+exports.verifyAesCmac = verifyAesCmac;
+const getMessageBlock = (message, blockIndex) => {
+ const block = Buffer.alloc(BLOCK_SIZE);
+ const start = blockIndex * BLOCK_SIZE;
+ const end = start + BLOCK_SIZE;
+ message.copy(block, 0, start, end);
+ return block;
+};
+const getPaddedMessageBlock = (message, blockIndex) => {
+ const block = Buffer.alloc(BLOCK_SIZE);
+ const start = blockIndex * BLOCK_SIZE;
+ const end = message.length;
+ block.fill(0);
+ message.copy(block, 0, start, end);
+ block[end - start] = 0x80;
+ return block;
+};
diff --git a/dist/buffer-utils.d.ts b/dist/buffer-utils.d.ts
new file mode 100644
index 0000000..4a074da
--- /dev/null
+++ b/dist/buffer-utils.d.ts
@@ -0,0 +1,3 @@
+///
+export declare const bitShiftLeft: (buffer: Buffer) => Buffer;
+export declare const xor: (buffer1: Buffer, buffer2: Buffer) => Buffer;
diff --git a/dist/buffer-utils.js b/dist/buffer-utils.js
new file mode 100644
index 0000000..fb7d666
--- /dev/null
+++ b/dist/buffer-utils.js
@@ -0,0 +1,13 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.xor = exports.bitShiftLeft = void 0;
+const bitShiftLeft = (buffer) => Buffer.alloc(buffer.length).map((_, i) => {
+ const x = buffer[i] << 1;
+ return buffer[i + 1] & 0x80 ? x + 0x01 : x;
+});
+exports.bitShiftLeft = bitShiftLeft;
+const xor = (buffer1, buffer2) => {
+ const length = Math.min(buffer1.length, buffer2.length);
+ return Buffer.alloc(length).map((_, i) => buffer1[i] ^ buffer2[i]);
+};
+exports.xor = xor;
diff --git a/dist/index.d.ts b/dist/index.d.ts
new file mode 100644
index 0000000..e61787a
--- /dev/null
+++ b/dist/index.d.ts
@@ -0,0 +1 @@
+export { generateAesCmac } from "./aes-cmac";
diff --git a/dist/index.js b/dist/index.js
new file mode 100644
index 0000000..a53dee6
--- /dev/null
+++ b/dist/index.js
@@ -0,0 +1,5 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.generateAesCmac = void 0;
+var aes_cmac_1 = require("./aes-cmac");
+Object.defineProperty(exports, "generateAesCmac", { enumerable: true, get: function () { return aes_cmac_1.generateAesCmac; } });