"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var operations_exports = {};
__export(operations_exports, {
  computeCMAC: () => computeCMAC,
  computeMAC: () => computeMAC,
  computeNoncePRK: () => computeNoncePRK,
  computePRK: () => computePRK,
  decryptAES128CCM: () => decryptAES128CCM,
  decryptAES128OFB: () => decryptAES128OFB,
  decryptAES256CBC: () => decryptAES256CBC,
  decryptChaCha20Poly1305: () => decryptChaCha20Poly1305,
  deriveMEI: () => deriveMEI,
  deriveNetworkKeys: () => deriveNetworkKeys,
  deriveSharedECDHSecret: () => deriveSharedECDHSecret,
  deriveTempKeys: () => deriveTempKeys,
  digest: () => digest,
  encryptAES128CBC: () => encryptAES128CBC,
  encryptAES128CCM: () => encryptAES128CCM,
  encryptAES128ECB: () => encryptAES128ECB,
  encryptAES128OFB: () => encryptAES128OFB,
  encryptChaCha20Poly1305: () => encryptChaCha20Poly1305,
  generateECDHKeyPair: () => generateECDHKeyPair,
  hmacSHA256: () => hmacSHA256,
  keyPairFromRawECDHPrivateKey: () => keyPairFromRawECDHPrivateKey,
  randomBytes: () => randomBytes
});
module.exports = __toCommonJS(operations_exports);
var import_shared = require("@zwave-js/shared");
var import_shared2 = require("./shared.js");
var import_crypto_primitives = require("#crypto_primitives");
const { decryptAES128OFB, encryptAES128CBC, encryptAES128ECB, encryptAES128OFB, encryptAES128CCM, decryptAES128CCM, decryptAES256CBC, randomBytes, digest, hmacSHA256, encryptChaCha20Poly1305, decryptChaCha20Poly1305, generateECDHKeyPair, deriveSharedECDHSecret, keyPairFromRawECDHPrivateKey } = import_crypto_primitives.primitives;
const Z128 = new Uint8Array(16).fill(0);
const R128 = import_shared.Bytes.from("00000000000000000000000000000087", "hex");
const constantPRK = new Uint8Array(16).fill(51);
const constantTE = new Uint8Array(15).fill(136);
const constantNK = new Uint8Array(15).fill(85);
const constantNonce = new Uint8Array(16).fill(38);
const constantEI = new Uint8Array(15).fill(136);
async function computeMAC(authData, key, iv = new Uint8Array(import_shared2.BLOCK_SIZE).fill(0)) {
  const ciphertext = await encryptAES128CBC(authData, key, iv);
  return ciphertext.subarray(ciphertext.length - import_shared2.BLOCK_SIZE).subarray(0, 8);
}
__name(computeMAC, "computeMAC");
async function generateAES128CMACSubkeys(key) {
  const L = await encryptAES128ECB(Z128, key);
  const k1 = !(L[0] & 128) ? (0, import_shared2.leftShift1)(L) : (0, import_shared2.xor)((0, import_shared2.leftShift1)(L), R128);
  const k2 = !(k1[0] & 128) ? (0, import_shared2.leftShift1)(k1) : (0, import_shared2.xor)((0, import_shared2.leftShift1)(k1), R128);
  return [k1, k2];
}
__name(generateAES128CMACSubkeys, "generateAES128CMACSubkeys");
async function computeCMAC(message, key) {
  const blockSize = 16;
  const numBlocks = Math.ceil(message.length / blockSize);
  let lastBlock = message.subarray((numBlocks - 1) * blockSize);
  const lastBlockIsComplete = message.length > 0 && message.length % blockSize === 0;
  if (!lastBlockIsComplete) {
    lastBlock = (0, import_shared2.zeroPad)(import_shared.Bytes.concat([lastBlock, [128]]), blockSize).output;
  }
  let ret = Z128;
  for (let i = 0; i < numBlocks - 1; i++) {
    ret = (0, import_shared2.xor)(ret, message.subarray(i * blockSize, (i + 1) * blockSize));
    ret = await encryptAES128ECB(ret, key);
  }
  const [k1, k2] = await generateAES128CMACSubkeys(key);
  ret = (0, import_shared2.xor)(ret, (0, import_shared2.xor)(lastBlockIsComplete ? k1 : k2, lastBlock));
  ret = await encryptAES128ECB(ret, key);
  return ret.subarray(0, blockSize);
}
__name(computeCMAC, "computeCMAC");
function computePRK(ecdhSharedSecret, pubKeyA, pubKeyB) {
  const message = import_shared.Bytes.concat([ecdhSharedSecret, pubKeyA, pubKeyB]);
  return computeCMAC(message, constantPRK);
}
__name(computePRK, "computePRK");
async function deriveTempKeys(PRK) {
  const T1 = await computeCMAC(import_shared.Bytes.concat([constantTE, [1]]), PRK);
  const T2 = await computeCMAC(import_shared.Bytes.concat([T1, constantTE, [2]]), PRK);
  const T3 = await computeCMAC(import_shared.Bytes.concat([T2, constantTE, [3]]), PRK);
  return {
    tempKeyCCM: T1,
    tempPersonalizationString: import_shared.Bytes.concat([T2, T3])
  };
}
__name(deriveTempKeys, "deriveTempKeys");
async function deriveNetworkKeys(PNK) {
  const T1 = await computeCMAC(import_shared.Bytes.concat([constantNK, [1]]), PNK);
  const T2 = await computeCMAC(import_shared.Bytes.concat([T1, constantNK, [2]]), PNK);
  const T3 = await computeCMAC(import_shared.Bytes.concat([T2, constantNK, [3]]), PNK);
  const T4 = await computeCMAC(import_shared.Bytes.concat([T3, constantNK, [4]]), PNK);
  return {
    keyCCM: T1,
    keyMPAN: T4,
    personalizationString: import_shared.Bytes.concat([T2, T3])
  };
}
__name(deriveNetworkKeys, "deriveNetworkKeys");
function computeNoncePRK(senderEI, receiverEI) {
  const message = import_shared.Bytes.concat([senderEI, receiverEI]);
  return computeCMAC(message, constantNonce);
}
__name(computeNoncePRK, "computeNoncePRK");
async function deriveMEI(noncePRK) {
  const T1 = await computeCMAC(import_shared.Bytes.concat([
    constantEI,
    [0],
    constantEI,
    [1]
  ]), noncePRK);
  const T2 = await computeCMAC(import_shared.Bytes.concat([T1, constantEI, [2]]), noncePRK);
  return import_shared.Bytes.concat([T1, T2]);
}
__name(deriveMEI, "deriveMEI");
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  computeCMAC,
  computeMAC,
  computeNoncePRK,
  computePRK,
  decryptAES128CCM,
  decryptAES128OFB,
  decryptAES256CBC,
  decryptChaCha20Poly1305,
  deriveMEI,
  deriveNetworkKeys,
  deriveSharedECDHSecret,
  deriveTempKeys,
  digest,
  encryptAES128CBC,
  encryptAES128CCM,
  encryptAES128ECB,
  encryptAES128OFB,
  encryptChaCha20Poly1305,
  generateECDHKeyPair,
  hmacSHA256,
  keyPairFromRawECDHPrivateKey,
  randomBytes
});
//# sourceMappingURL=operations.js.map
