"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
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 PaseClient_exports = {};
__export(PaseClient_exports, {
  PaseClient: () => PaseClient
});
module.exports = __toCommonJS(PaseClient_exports);
var import_Mark = require("#common/Mark.js");
var import_general = require("#general");
var import_types = require("#types");
var import_PaseMessenger = require("./PaseMessenger.js");
/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
const { numberToBytesBE } = import_general.ec;
const logger = import_general.Logger.get("PaseClient");
class PaseClient {
  #sessions;
  constructor(sessions) {
    this.#sessions = sessions;
  }
  static async generatePakePasscodeVerifier(crypto, setupPinCode, pbkdfParameters) {
    const { w0, L } = await import_general.Spake2p.computeW0L(crypto, pbkdfParameters, setupPinCode);
    return import_general.Bytes.concat(numberToBytesBE(w0, 32), L);
  }
  static generateRandomPasscode(crypto) {
    let passcode;
    passcode = crypto.randomUint32 % 99999998 + 1;
    if (import_types.CommissioningOptions.FORBIDDEN_PASSCODES.includes(passcode)) {
      passcode += 1;
    }
    return passcode;
  }
  static generateRandomDiscriminator(crypto) {
    return crypto.randomUint16 % 4096;
  }
  async pair(initiatorSessionParams, exchange, channel, setupPin) {
    const messenger = new import_PaseMessenger.PaseClientMessenger(exchange);
    const { crypto } = this.#sessions;
    const initiatorRandom = crypto.randomBytes(32);
    const initiatorSessionId = await this.#sessions.getNextAvailableSessionId();
    const requestPayload = await messenger.sendPbkdfParamRequest({
      initiatorRandom,
      initiatorSessionId,
      passcodeId: import_PaseMessenger.DEFAULT_PASSCODE_ID,
      hasPbkdfParameters: false,
      initiatorSessionParams
    });
    const {
      responsePayload,
      response: { pbkdfParameters, responderSessionId, responderSessionParams }
    } = await messenger.readPbkdfParamResponse();
    if (pbkdfParameters === void 0) {
      await messenger.sendError(import_types.SecureChannelStatusCode.InvalidParam);
      throw new import_general.UnexpectedDataError("Missing requested PbkdfParameters in the response. Commissioning failed.");
    }
    if (responderSessionParams !== void 0) {
      exchange.session.timingParameters = responderSessionParams;
    }
    const peerSessionParameters = {
      ...exchange.session.parameters,
      ...responderSessionParams ?? {}
    };
    const { w0, w1 } = await import_general.Spake2p.computeW0W1(crypto, pbkdfParameters, setupPin);
    const spake2p = import_general.Spake2p.create(
      crypto,
      await crypto.computeHash([import_PaseMessenger.SPAKE_CONTEXT, requestPayload, responsePayload]),
      w0
    );
    const X = spake2p.computeX();
    await messenger.sendPasePake1({ x: X });
    const { y: Y, verifier } = await messenger.readPasePake2();
    const { Ke, hAY, hBX } = await spake2p.computeSecretAndVerifiersFromY(w1, X, Y);
    if (!import_general.Bytes.areEqual(verifier, hBX)) {
      await messenger.sendError(import_types.SecureChannelStatusCode.InvalidParam);
      throw new import_general.UnexpectedDataError(
        "Received incorrect key confirmation from the receiver. Commissioning failed."
      );
    }
    await messenger.sendPasePake3({ verifier: hAY });
    await messenger.waitForSuccess("PasePake3-Success");
    const secureSession = await this.#sessions.createSecureSession({
      channel,
      id: initiatorSessionId,
      fabric: void 0,
      peerNodeId: import_types.NodeId.UNSPECIFIED_NODE_ID,
      peerSessionId: responderSessionId,
      sharedSecret: Ke,
      salt: new Uint8Array(0),
      isInitiator: true,
      isResumption: false,
      peerSessionParameters
    });
    await messenger.close();
    logger.info("Paired successfully", import_Mark.Mark.OUTBOUND, messenger.channelName, exchange.diagnostics);
    return secureSession;
  }
}
//# sourceMappingURL=PaseClient.js.map
