"use strict";
((window) => {
  const core = window.Deno.core;
  const webidl = window.__bootstrap.webidl;
  const { DOMException } = window.__bootstrap.domException;
  const { TextEncoder, TextDecoder } = window.__bootstrap.encoding;
  const {
    ArrayBuffer,
    ArrayBufferIsView,
    ArrayPrototypeEvery,
    ArrayPrototypeFind,
    ArrayPrototypeIncludes,
    BigInt64Array,
    Int16Array,
    Int32Array,
    Int8Array,
    JSONParse,
    JSONStringify,
    ObjectAssign,
    StringPrototypeToLowerCase,
    StringPrototypeToUpperCase,
    Symbol,
    SymbolFor,
    SyntaxError,
    TypedArrayPrototypeSlice,
    TypeError,
    Uint16Array,
    Uint32Array,
    Uint8Array,
    Uint8ClampedArray,
    WeakMap,
    WeakMapPrototypeGet,
    WeakMapPrototypeSet,
  } = window.__bootstrap.primordials;
    const supportedNamedCurves = ["P-256", "P-384"];
  const recognisedUsages = [
    "encrypt",
    "decrypt",
    "sign",
    "verify",
    "deriveKey",
    "deriveBits",
    "wrapKey",
    "unwrapKey",
  ];
  const simpleAlgorithmDictionaries = {
    AesGcmParams: { iv: "BufferSource", additionalData: "BufferSource" },
    RsaHashedKeyGenParams: { hash: "HashAlgorithmIdentifier" },
    EcKeyGenParams: {},
    HmacKeyGenParams: { hash: "HashAlgorithmIdentifier" },
    RsaPssParams: {},
    EcdsaParams: { hash: "HashAlgorithmIdentifier" },
    HmacImportParams: { hash: "HashAlgorithmIdentifier" },
    HkdfParams: {
      hash: "HashAlgorithmIdentifier",
      salt: "BufferSource",
      info: "BufferSource",
    },
    Pbkdf2Params: { hash: "HashAlgorithmIdentifier", salt: "BufferSource" },
    RsaOaepParams: { label: "BufferSource" },
    RsaHashedImportParams: { hash: "HashAlgorithmIdentifier" },
    EcKeyImportParams: {},
  };
  const supportedAlgorithms = {
    "digest": {
      "SHA-1": null,
      "SHA-256": null,
      "SHA-384": null,
      "SHA-512": null,
    },
    "generateKey": {
      "RSASSA-PKCS1-v1_5": "RsaHashedKeyGenParams",
      "RSA-PSS": "RsaHashedKeyGenParams",
      "RSA-OAEP": "RsaHashedKeyGenParams",
      "ECDSA": "EcKeyGenParams",
      "ECDH": "EcKeyGenParams",
      "AES-CTR": "AesKeyGenParams",
      "AES-CBC": "AesKeyGenParams",
      "AES-GCM": "AesKeyGenParams",
      "AES-KW": "AesKeyGenParams",
      "HMAC": "HmacKeyGenParams",
    },
    "sign": {
      "RSASSA-PKCS1-v1_5": null,
      "RSA-PSS": "RsaPssParams",
      "ECDSA": "EcdsaParams",
      "HMAC": null,
    },
    "verify": {
      "RSASSA-PKCS1-v1_5": null,
      "RSA-PSS": "RsaPssParams",
      "ECDSA": "EcdsaParams",
      "HMAC": null,
    },
    "importKey": {
      "RSASSA-PKCS1-v1_5": "RsaHashedImportParams",
      "RSA-PSS": "RsaHashedImportParams",
      "RSA-OAEP": "RsaHashedImportParams",
      "ECDSA": "EcKeyImportParams",
      "ECDH": "EcKeyImportParams",
      "HMAC": "HmacImportParams",
      "HKDF": null,
      "PBKDF2": null,
      "AES-CTR": null,
      "AES-CBC": null,
      "AES-GCM": null,
      "AES-KW": null,
    },
    "deriveBits": {
      "HKDF": "HkdfParams",
      "PBKDF2": "Pbkdf2Params",
      "ECDH": "EcdhKeyDeriveParams",
    },
    "encrypt": {
      "RSA-OAEP": "RsaOaepParams",
      "AES-CBC": "AesCbcParams",
      "AES-GCM": "AesGcmParams",
      "AES-CTR": "AesCtrParams",
    },
    "decrypt": {
      "RSA-OAEP": "RsaOaepParams",
      "AES-CBC": "AesCbcParams",
      "AES-GCM": "AesGcmParams",
      "AES-CTR": "AesCtrParams",
    },
    "get key length": {
      "AES-CBC": "AesDerivedKeyParams",
      "AES-CTR": "AesDerivedKeyParams",
      "AES-GCM": "AesDerivedKeyParams",
      "AES-KW": "AesDerivedKeyParams",
      "HMAC": "HmacImportParams",
      "HKDF": null,
      "PBKDF2": null,
    },
    "wrapKey": {
      "AES-KW": null,
    },
    "unwrapKey": {
      "AES-KW": null,
    },
  };
  const aesJwkAlg = {
    "AES-CTR": {
      128: "A128CTR",
      192: "A192CTR",
      256: "A256CTR",
    },
    "AES-CBC": {
      128: "A128CBC",
      192: "A192CBC",
      256: "A256CBC",
    },
    "AES-GCM": {
      128: "A128GCM",
      192: "A192GCM",
      256: "A256GCM",
    },
    "AES-KW": {
      128: "A128KW",
      192: "A192KW",
      256: "A256KW",
    },
  };
      function normalizeAlgorithm(algorithm, op) {
    if (typeof algorithm == "string") {
      return normalizeAlgorithm({ name: algorithm }, op);
    }
        const registeredAlgorithms = supportedAlgorithms[op];
        const initialAlg = webidl.converters.Algorithm(algorithm, {
      prefix: "Failed to normalize algorithm",
      context: "passed algorithm",
    });
        let algName = initialAlg.name;
        let desiredType = undefined;
    for (const key in registeredAlgorithms) {
      if (
        StringPrototypeToUpperCase(key) === StringPrototypeToUpperCase(algName)
      ) {
        algName = key;
        desiredType = registeredAlgorithms[key];
      }
    }
    if (desiredType === undefined) {
      throw new DOMException(
        "Unrecognized algorithm name",
        "NotSupportedError",
      );
    }
        if (desiredType === null) {
      return { name: algName };
    }
        const normalizedAlgorithm = webidl.converters[desiredType](algorithm, {
      prefix: "Failed to normalize algorithm",
      context: "passed algorithm",
    });
        normalizedAlgorithm.name = algName;
        const dict = simpleAlgorithmDictionaries[desiredType];
        for (const member in dict) {
      const idlType = dict[member];
      const idlValue = normalizedAlgorithm[member];
            if (idlType === "BufferSource" && idlValue) {
        normalizedAlgorithm[member] = TypedArrayPrototypeSlice(
          new Uint8Array(
            ArrayBufferIsView(idlValue) ? idlValue.buffer : idlValue,
            idlValue.byteOffset ?? 0,
            idlValue.byteLength,
          ),
        );
      } else if (idlType === "HashAlgorithmIdentifier") {
        normalizedAlgorithm[member] = normalizeAlgorithm(idlValue, "digest");
      } else if (idlType === "AlgorithmIdentifier") {
                throw new TypeError("unimplemented");
      }
    }
    return normalizedAlgorithm;
  }
  
  function copyBuffer(input) {
    return TypedArrayPrototypeSlice(
      ArrayBufferIsView(input)
        ? new Uint8Array(input.buffer, input.byteOffset, input.byteLength)
        : new Uint8Array(input),
    );
  }
  const _handle = Symbol("[[handle]]");
  const _algorithm = Symbol("[[algorithm]]");
  const _extractable = Symbol("[[extractable]]");
  const _usages = Symbol("[[usages]]");
  const _type = Symbol("[[type]]");
  class CryptoKey {
    
    [_type];
    
    [_extractable];
    
    [_algorithm];
    
    [_usages];
    
    [_handle];
    constructor() {
      webidl.illegalConstructor();
    }
    
    get type() {
      webidl.assertBranded(this, CryptoKey);
      return this[_type];
    }
    
    get extractable() {
      webidl.assertBranded(this, CryptoKey);
      return this[_extractable];
    }
    
    get usages() {
      webidl.assertBranded(this, CryptoKey);
            return this[_usages];
    }
    
    get algorithm() {
      webidl.assertBranded(this, CryptoKey);
            return this[_algorithm];
    }
    [SymbolFor("Deno.customInspect")](inspect) {
      return `${this.constructor.name} ${
        inspect({
          type: this.type,
          extractable: this.extractable,
          algorithm: this.algorithm,
          usages: this.usages,
        })
      }`;
    }
  }
  webidl.configurePrototype(CryptoKey);
  
  function constructKey(type, extractable, usages, algorithm, handle) {
    const key = webidl.createBranded(CryptoKey);
    key[_type] = type;
    key[_extractable] = extractable;
    key[_usages] = usages;
    key[_algorithm] = algorithm;
    key[_handle] = handle;
    return key;
  }
    
  function usageIntersection(a, b) {
    return a.filter((i) => b.includes(i));
  }
    
  const KEY_STORE = new WeakMap();
  function getKeyLength(algorithm) {
    switch (algorithm.name) {
      case "AES-CBC":
      case "AES-CTR":
      case "AES-GCM":
      case "AES-KW": {
                if (!ArrayPrototypeIncludes([128, 192, 256], algorithm.length)) {
          throw new DOMException(
            "length must be 128, 192, or 256",
            "OperationError",
          );
        }
                return algorithm.length;
      }
      case "HMAC": {
                let length;
        if (algorithm.length === undefined) {
          switch (algorithm.hash.name) {
            case "SHA-1":
              length = 160;
              break;
            case "SHA-256":
              length = 256;
              break;
            case "SHA-384":
              length = 384;
              break;
            case "SHA-512":
              length = 512;
              break;
            default:
              throw new DOMException(
                "Unrecognized hash algorithm",
                "NotSupportedError",
              );
          }
        } else if (algorithm.length !== 0) {
          length = algorithm.length;
        } else {
          throw new TypeError("Invalid length.");
        }
                return length;
      }
      case "HKDF": {
                return null;
      }
      case "PBKDF2": {
                return null;
      }
      default:
        throw new TypeError("unreachable");
    }
  }
  class SubtleCrypto {
    constructor() {
      webidl.illegalConstructor();
    }
    
    async digest(algorithm, data) {
      webidl.assertBranded(this, SubtleCrypto);
      const prefix = "Failed to execute 'digest' on 'SubtleCrypto'";
      webidl.requiredArguments(arguments.length, 2, { prefix });
      algorithm = webidl.converters.AlgorithmIdentifier(algorithm, {
        prefix,
        context: "Argument 1",
      });
      data = webidl.converters.BufferSource(data, {
        prefix,
        context: "Argument 2",
      });
      data = copyBuffer(data);
      algorithm = normalizeAlgorithm(algorithm, "digest");
      const result = await core.opAsync(
        "op_crypto_subtle_digest",
        algorithm.name,
        data,
      );
      return result.buffer;
    }
    
    async encrypt(algorithm, key, data) {
      webidl.assertBranded(this, SubtleCrypto);
      const prefix = "Failed to execute 'encrypt' on 'SubtleCrypto'";
      webidl.requiredArguments(arguments.length, 3, { prefix });
      algorithm = webidl.converters.AlgorithmIdentifier(algorithm, {
        prefix,
        context: "Argument 1",
      });
      key = webidl.converters.CryptoKey(key, {
        prefix,
        context: "Argument 2",
      });
      data = webidl.converters.BufferSource(data, {
        prefix,
        context: "Argument 3",
      });
            data = copyBuffer(data);
            const normalizedAlgorithm = normalizeAlgorithm(algorithm, "encrypt");
            if (normalizedAlgorithm.name !== key[_algorithm].name) {
        throw new DOMException(
          "Encryption algorithm doesn't match key algorithm.",
          "InvalidAccessError",
        );
      }
            if (!ArrayPrototypeIncludes(key[_usages], "encrypt")) {
        throw new DOMException(
          "Key does not support the 'encrypt' operation.",
          "InvalidAccessError",
        );
      }
      return await encrypt(normalizedAlgorithm, key, data);
    }
    
    async decrypt(algorithm, key, data) {
      webidl.assertBranded(this, SubtleCrypto);
      const prefix = "Failed to execute 'decrypt' on 'SubtleCrypto'";
      webidl.requiredArguments(arguments.length, 3, { prefix });
      algorithm = webidl.converters.AlgorithmIdentifier(algorithm, {
        prefix,
        context: "Argument 1",
      });
      key = webidl.converters.CryptoKey(key, {
        prefix,
        context: "Argument 2",
      });
      data = webidl.converters.BufferSource(data, {
        prefix,
        context: "Argument 3",
      });
            data = copyBuffer(data);
            const normalizedAlgorithm = normalizeAlgorithm(algorithm, "decrypt");
            if (normalizedAlgorithm.name !== key[_algorithm].name) {
        throw new DOMException(
          "Decryption algorithm doesn't match key algorithm.",
          "OperationError",
        );
      }
            if (!ArrayPrototypeIncludes(key[_usages], "decrypt")) {
        throw new DOMException(
          "Key does not support the 'decrypt' operation.",
          "InvalidAccessError",
        );
      }
      const handle = key[_handle];
      const keyData = WeakMapPrototypeGet(KEY_STORE, handle);
      switch (normalizedAlgorithm.name) {
        case "RSA-OAEP": {
                    if (key[_type] !== "private") {
            throw new DOMException(
              "Key type not supported",
              "InvalidAccessError",
            );
          }
                    if (normalizedAlgorithm.label) {
            normalizedAlgorithm.label = copyBuffer(normalizedAlgorithm.label);
          } else {
            normalizedAlgorithm.label = new Uint8Array();
          }
                    const hashAlgorithm = key[_algorithm].hash.name;
          const plainText = await core.opAsync("op_crypto_decrypt", {
            key: keyData,
            algorithm: "RSA-OAEP",
            hash: hashAlgorithm,
            label: normalizedAlgorithm.label,
          }, data);
                    return plainText.buffer;
        }
        case "AES-CBC": {
          normalizedAlgorithm.iv = copyBuffer(normalizedAlgorithm.iv);
                    if (normalizedAlgorithm.iv.byteLength !== 16) {
            throw new DOMException(
              "Counter must be 16 bytes",
              "OperationError",
            );
          }
          const plainText = await core.opAsync("op_crypto_decrypt", {
            key: keyData,
            algorithm: "AES-CBC",
            iv: normalizedAlgorithm.iv,
            length: key[_algorithm].length,
          }, data);
                    return plainText.buffer;
        }
        case "AES-CTR": {
          normalizedAlgorithm.counter = copyBuffer(normalizedAlgorithm.counter);
                    if (normalizedAlgorithm.counter.byteLength !== 16) {
            throw new DOMException(
              "Counter vector must be 16 bytes",
              "OperationError",
            );
          }
                    if (
            normalizedAlgorithm.length === 0 || normalizedAlgorithm.length > 128
          ) {
            throw new DOMException(
              "Counter length must not be 0 or greater than 128",
              "OperationError",
            );
          }
                    const cipherText = await core.opAsync("op_crypto_decrypt", {
            key: keyData,
            algorithm: "AES-CTR",
            keyLength: key[_algorithm].length,
            counter: normalizedAlgorithm.counter,
            ctrLength: normalizedAlgorithm.length,
          }, data);
                    return cipherText.buffer;
        }
        case "AES-GCM": {
          normalizedAlgorithm.iv = copyBuffer(normalizedAlgorithm.iv);
                    if (normalizedAlgorithm.tagLength === undefined) {
            normalizedAlgorithm.tagLength = 128;
          } else if (
            !ArrayPrototypeIncludes(
              [32, 64, 96, 104, 112, 120, 128],
              normalizedAlgorithm.tagLength,
            )
          ) {
            throw new DOMException(
              "Invalid tag length",
              "OperationError",
            );
          }
                    if (data.byteLength < normalizedAlgorithm.tagLength / 8) {
            throw new DOMException(
              "Tag length overflows ciphertext",
              "OperationError",
            );
          }
                    if (normalizedAlgorithm.iv.byteLength !== 12) {
            throw new DOMException(
              "Initialization vector length not supported",
              "NotSupportedError",
            );
          }
                    if (normalizedAlgorithm.additionalData !== undefined) {
            if (normalizedAlgorithm.additionalData.byteLength > (2 ** 64) - 1) {
              throw new DOMException(
                "Additional data too large",
                "OperationError",
              );
            }
            normalizedAlgorithm.additionalData = copyBuffer(
              normalizedAlgorithm.additionalData,
            );
          }
                    const plaintext = await core.opAsync("op_crypto_decrypt", {
            key: keyData,
            algorithm: "AES-GCM",
            length: key[_algorithm].length,
            iv: normalizedAlgorithm.iv,
            additionalData: normalizedAlgorithm.additionalData,
            tagLength: normalizedAlgorithm.tagLength,
          }, data);
                    return plaintext.buffer;
        }
        default:
          throw new DOMException("Not implemented", "NotSupportedError");
      }
    }
    
    async sign(algorithm, key, data) {
      webidl.assertBranded(this, SubtleCrypto);
      const prefix = "Failed to execute 'sign' on 'SubtleCrypto'";
      webidl.requiredArguments(arguments.length, 3, { prefix });
      algorithm = webidl.converters.AlgorithmIdentifier(algorithm, {
        prefix,
        context: "Argument 1",
      });
      key = webidl.converters.CryptoKey(key, {
        prefix,
        context: "Argument 2",
      });
      data = webidl.converters.BufferSource(data, {
        prefix,
        context: "Argument 3",
      });
            data = copyBuffer(data);
            const normalizedAlgorithm = normalizeAlgorithm(algorithm, "sign");
      const handle = key[_handle];
      const keyData = WeakMapPrototypeGet(KEY_STORE, handle);
            if (normalizedAlgorithm.name !== key[_algorithm].name) {
        throw new DOMException(
          "Signing algorithm doesn't match key algorithm.",
          "InvalidAccessError",
        );
      }
            if (!ArrayPrototypeIncludes(key[_usages], "sign")) {
        throw new DOMException(
          "Key does not support the 'sign' operation.",
          "InvalidAccessError",
        );
      }
      switch (normalizedAlgorithm.name) {
        case "RSASSA-PKCS1-v1_5": {
                    if (key[_type] !== "private") {
            throw new DOMException(
              "Key type not supported",
              "InvalidAccessError",
            );
          }
                    const hashAlgorithm = key[_algorithm].hash.name;
          const signature = await core.opAsync("op_crypto_sign_key", {
            key: keyData,
            algorithm: "RSASSA-PKCS1-v1_5",
            hash: hashAlgorithm,
          }, data);
          return signature.buffer;
        }
        case "RSA-PSS": {
                    if (key[_type] !== "private") {
            throw new DOMException(
              "Key type not supported",
              "InvalidAccessError",
            );
          }
                    const hashAlgorithm = key[_algorithm].hash.name;
          const signature = await core.opAsync("op_crypto_sign_key", {
            key: keyData,
            algorithm: "RSA-PSS",
            hash: hashAlgorithm,
            saltLength: normalizedAlgorithm.saltLength,
          }, data);
          return signature.buffer;
        }
        case "ECDSA": {
                    if (key[_type] !== "private") {
            throw new DOMException(
              "Key type not supported",
              "InvalidAccessError",
            );
          }
                    const hashAlgorithm = normalizedAlgorithm.hash.name;
          const namedCurve = key[_algorithm].namedCurve;
          if (!ArrayPrototypeIncludes(supportedNamedCurves, namedCurve)) {
            throw new DOMException("Curve not supported", "NotSupportedError");
          }
          const signature = await core.opAsync("op_crypto_sign_key", {
            key: keyData,
            algorithm: "ECDSA",
            hash: hashAlgorithm,
            namedCurve,
          }, data);
          return signature.buffer;
        }
        case "HMAC": {
          const hashAlgorithm = key[_algorithm].hash.name;
          const signature = await core.opAsync("op_crypto_sign_key", {
            key: keyData,
            algorithm: "HMAC",
            hash: hashAlgorithm,
          }, data);
          return signature.buffer;
        }
      }
      throw new TypeError("unreachable");
    }
    
        async importKey(format, keyData, algorithm, extractable, keyUsages) {
      webidl.assertBranded(this, SubtleCrypto);
      const prefix = "Failed to execute 'importKey' on 'SubtleCrypto'";
      webidl.requiredArguments(arguments.length, 4, { prefix });
      format = webidl.converters.KeyFormat(format, {
        prefix,
        context: "Argument 1",
      });
      keyData = webidl.converters["BufferSource or JsonWebKey"](keyData, {
        prefix,
        context: "Argument 2",
      });
      algorithm = webidl.converters.AlgorithmIdentifier(algorithm, {
        prefix,
        context: "Argument 3",
      });
      extractable = webidl.converters.boolean(extractable, {
        prefix,
        context: "Argument 4",
      });
      keyUsages = webidl.converters["sequence<KeyUsage>"](keyUsages, {
        prefix,
        context: "Argument 5",
      });
            if (format !== "jwk") {
        if (ArrayBufferIsView(keyData) || keyData instanceof ArrayBuffer) {
          keyData = copyBuffer(keyData);
        } else {
          throw new TypeError("keyData is a JsonWebKey");
        }
      } else {
        if (ArrayBufferIsView(keyData) || keyData instanceof ArrayBuffer) {
          throw new TypeError("keyData is not a JsonWebKey");
        }
      }
      const normalizedAlgorithm = normalizeAlgorithm(algorithm, "importKey");
      const algorithmName = normalizedAlgorithm.name;
      switch (algorithmName) {
        case "HMAC": {
          return importKeyHMAC(
            format,
            normalizedAlgorithm,
            keyData,
            extractable,
            keyUsages,
          );
        }
        case "ECDH":
        case "ECDSA": {
          return importKeyEC(
            format,
            normalizedAlgorithm,
            keyData,
            extractable,
            keyUsages,
          );
        }
        case "RSASSA-PKCS1-v1_5":
        case "RSA-PSS":
        case "RSA-OAEP": {
          return importKeyRSA(
            format,
            normalizedAlgorithm,
            keyData,
            extractable,
            keyUsages,
          );
        }
        case "HKDF": {
          return importKeyHKDF(format, keyData, extractable, keyUsages);
        }
        case "PBKDF2": {
          return importKeyPBKDF2(format, keyData, extractable, keyUsages);
        }
        case "AES-CTR":
        case "AES-CBC":
        case "AES-GCM": {
          return importKeyAES(
            format,
            normalizedAlgorithm,
            keyData,
            extractable,
            keyUsages,
            ["encrypt", "decrypt", "wrapKey", "unwrapKey"],
          );
        }
        case "AES-KW": {
          return importKeyAES(
            format,
            normalizedAlgorithm,
            keyData,
            extractable,
            keyUsages,
            ["wrapKey", "unwrapKey"],
          );
        }
        default:
          throw new DOMException("Not implemented", "NotSupportedError");
      }
    }
    
        async exportKey(format, key) {
      webidl.assertBranded(this, SubtleCrypto);
      const prefix = "Failed to execute 'exportKey' on 'SubtleCrypto'";
      webidl.requiredArguments(arguments.length, 2, { prefix });
      format = webidl.converters.KeyFormat(format, {
        prefix,
        context: "Argument 1",
      });
      key = webidl.converters.CryptoKey(key, {
        prefix,
        context: "Argument 2",
      });
      const handle = key[_handle];
            const innerKey = WeakMapPrototypeGet(KEY_STORE, handle);
      const algorithmName = key[_algorithm].name;
      switch (algorithmName) {
        case "HMAC": {
          return exportKeyHMAC(format, key, innerKey);
        }
        case "RSASSA-PKCS1-v1_5":
        case "RSA-PSS":
        case "RSA-OAEP": {
          return exportKeyRSA(format, key, innerKey);
        }
        case "ECDH":
        case "ECDSA": {
          return exportKeyEC(format, key, innerKey);
        }
        case "AES-CTR":
        case "AES-CBC":
        case "AES-GCM":
        case "AES-KW": {
          return exportKeyAES(format, key, innerKey);
        }
                default:
          throw new DOMException("Not implemented", "NotSupportedError");
      }
    }
    
    async deriveBits(algorithm, baseKey, length) {
      webidl.assertBranded(this, SubtleCrypto);
      const prefix = "Failed to execute 'deriveBits' on 'SubtleCrypto'";
      webidl.requiredArguments(arguments.length, 3, { prefix });
      algorithm = webidl.converters.AlgorithmIdentifier(algorithm, {
        prefix,
        context: "Argument 1",
      });
      baseKey = webidl.converters.CryptoKey(baseKey, {
        prefix,
        context: "Argument 2",
      });
      length = webidl.converters["unsigned long"](length, {
        prefix,
        context: "Argument 3",
      });
            const normalizedAlgorithm = normalizeAlgorithm(algorithm, "deriveBits");
            const result = await deriveBits(normalizedAlgorithm, baseKey, length);
            if (normalizedAlgorithm.name !== baseKey[_algorithm].name) {
        throw new DOMException("Invalid algorithm name", "InvalidAccessError");
      }
            if (!ArrayPrototypeIncludes(baseKey[_usages], "deriveBits")) {
        throw new DOMException(
          "baseKey usages does not contain `deriveBits`",
          "InvalidAccessError",
        );
      }
            return result;
    }
    
    async deriveKey(
      algorithm,
      baseKey,
      derivedKeyType,
      extractable,
      keyUsages,
    ) {
      webidl.assertBranded(this, SubtleCrypto);
      const prefix = "Failed to execute 'deriveKey' on 'SubtleCrypto'";
      webidl.requiredArguments(arguments.length, 5, { prefix });
      algorithm = webidl.converters.AlgorithmIdentifier(algorithm, {
        prefix,
        context: "Argument 1",
      });
      baseKey = webidl.converters.CryptoKey(baseKey, {
        prefix,
        context: "Argument 2",
      });
      derivedKeyType = webidl.converters.AlgorithmIdentifier(derivedKeyType, {
        prefix,
        context: "Argument 3",
      });
      extractable = webidl.converters["boolean"](extractable, {
        prefix,
        context: "Argument 4",
      });
      keyUsages = webidl.converters["sequence<KeyUsage>"](keyUsages, {
        prefix,
        context: "Argument 5",
      });
            const normalizedAlgorithm = normalizeAlgorithm(algorithm, "deriveBits");
            const normalizedDerivedKeyAlgorithmImport = normalizeAlgorithm(
        derivedKeyType,
        "importKey",
      );
            const normalizedDerivedKeyAlgorithmLength = normalizeAlgorithm(
        derivedKeyType,
        "get key length",
      );
      
            if (normalizedAlgorithm.name !== baseKey[_algorithm].name) {
        throw new DOMException(
          "Invalid algorithm name",
          "InvalidAccessError",
        );
      }
            if (!ArrayPrototypeIncludes(baseKey[_usages], "deriveKey")) {
        throw new DOMException(
          "baseKey usages does not contain `deriveKey`",
          "InvalidAccessError",
        );
      }
            const length = getKeyLength(normalizedDerivedKeyAlgorithmLength);
            const secret = await this.deriveBits(
        normalizedAlgorithm,
        baseKey,
        length,
      );
            const result = await this.importKey(
        "raw",
        secret,
        normalizedDerivedKeyAlgorithmImport,
        extractable,
        keyUsages,
      );
            if (
        ArrayPrototypeIncludes(["private", "secret"], result[_type]) &&
        keyUsages.length == 0
      ) {
        throw new SyntaxError("Invalid key usages");
      }
            return result;
    }
    
    async verify(algorithm, key, signature, data) {
      webidl.assertBranded(this, SubtleCrypto);
      const prefix = "Failed to execute 'verify' on 'SubtleCrypto'";
      webidl.requiredArguments(arguments.length, 4, { prefix });
      algorithm = webidl.converters.AlgorithmIdentifier(algorithm, {
        prefix,
        context: "Argument 1",
      });
      key = webidl.converters.CryptoKey(key, {
        prefix,
        context: "Argument 2",
      });
      signature = webidl.converters.BufferSource(signature, {
        prefix,
        context: "Argument 3",
      });
      data = webidl.converters.BufferSource(data, {
        prefix,
        context: "Argument 4",
      });
            signature = copyBuffer(signature);
            data = copyBuffer(data);
      const normalizedAlgorithm = normalizeAlgorithm(algorithm, "verify");
      const handle = key[_handle];
      const keyData = WeakMapPrototypeGet(KEY_STORE, handle);
      if (normalizedAlgorithm.name !== key[_algorithm].name) {
        throw new DOMException(
          "Verifying algorithm doesn't match key algorithm.",
          "InvalidAccessError",
        );
      }
      if (!ArrayPrototypeIncludes(key[_usages], "verify")) {
        throw new DOMException(
          "Key does not support the 'verify' operation.",
          "InvalidAccessError",
        );
      }
      switch (normalizedAlgorithm.name) {
        case "RSASSA-PKCS1-v1_5": {
          if (key[_type] !== "public") {
            throw new DOMException(
              "Key type not supported",
              "InvalidAccessError",
            );
          }
          const hashAlgorithm = key[_algorithm].hash.name;
          return await core.opAsync("op_crypto_verify_key", {
            key: keyData,
            algorithm: "RSASSA-PKCS1-v1_5",
            hash: hashAlgorithm,
            signature,
          }, data);
        }
        case "RSA-PSS": {
          if (key[_type] !== "public") {
            throw new DOMException(
              "Key type not supported",
              "InvalidAccessError",
            );
          }
          const hashAlgorithm = key[_algorithm].hash.name;
          const saltLength = normalizedAlgorithm.saltLength;
          return await core.opAsync("op_crypto_verify_key", {
            key: keyData,
            algorithm: "RSA-PSS",
            hash: hashAlgorithm,
            saltLength,
            signature,
          }, data);
        }
        case "HMAC": {
          const hash = key[_algorithm].hash.name;
          return await core.opAsync("op_crypto_verify_key", {
            key: keyData,
            algorithm: "HMAC",
            hash,
            signature,
          }, data);
        }
        case "ECDSA": {
                    if (key[_type] !== "public") {
            throw new DOMException(
              "Key type not supported",
              "InvalidAccessError",
            );
          }
                    const hash = normalizedAlgorithm.hash.name;
                    return await core.opAsync("op_crypto_verify_key", {
            key: keyData,
            algorithm: "ECDSA",
            hash,
            signature,
            namedCurve: key[_algorithm].namedCurve,
          }, data);
        }
      }
      throw new TypeError("unreachable");
    }
    
    async wrapKey(format, key, wrappingKey, wrapAlgorithm) {
      webidl.assertBranded(this, SubtleCrypto);
      const prefix = "Failed to execute 'wrapKey' on 'SubtleCrypto'";
      webidl.requiredArguments(arguments.length, 4, { prefix });
      format = webidl.converters.KeyFormat(format, {
        prefix,
        context: "Argument 1",
      });
      key = webidl.converters.CryptoKey(key, {
        prefix,
        context: "Argument 2",
      });
      wrappingKey = webidl.converters.CryptoKey(wrappingKey, {
        prefix,
        context: "Argument 3",
      });
      wrapAlgorithm = webidl.converters.AlgorithmIdentifier(wrapAlgorithm, {
        prefix,
        context: "Argument 4",
      });
      let normalizedAlgorithm;
      try {
                normalizedAlgorithm = normalizeAlgorithm(wrapAlgorithm, "wrapKey");
      } catch (_) {
                normalizedAlgorithm = normalizeAlgorithm(wrapAlgorithm, "encrypt");
      }
            if (normalizedAlgorithm.name !== wrappingKey[_algorithm].name) {
        throw new DOMException(
          "Wrapping algorithm doesn't match key algorithm.",
          "InvalidAccessError",
        );
      }
            if (!ArrayPrototypeIncludes(wrappingKey[_usages], "wrapKey")) {
        throw new DOMException(
          "Key does not support the 'wrapKey' operation.",
          "InvalidAccessError",
        );
      }
                  if (key[_extractable] === false) {
        throw new DOMException(
          "Key is not extractable",
          "InvalidAccessError",
        );
      }
            const exportedKey = await this.exportKey(format, key);
      let bytes;
            if (format !== "jwk") {
        bytes = new Uint8Array(exportedKey);
      } else {
        const jwk = JSONStringify(exportedKey);
        bytes = new TextEncoder("utf-8").encode(jwk);
      }
            if (
        supportedAlgorithms["wrapKey"][normalizedAlgorithm.name] !== undefined
      ) {
        const handle = wrappingKey[_handle];
        const keyData = WeakMapPrototypeGet(KEY_STORE, handle);
        switch (normalizedAlgorithm.name) {
          case "AES-KW": {
            const cipherText = await core.opSync("op_crypto_wrap_key", {
              key: keyData,
              algorithm: normalizedAlgorithm.name,
            }, bytes);
                        return cipherText.buffer;
          }
          default: {
            throw new DOMException(
              "Not implemented",
              "NotSupportedError",
            );
          }
        }
      } else if (
        supportedAlgorithms["encrypt"][normalizedAlgorithm.name] !== undefined
      ) {
                return await encrypt(
          normalizedAlgorithm,
          constructKey(
            wrappingKey[_type],
            wrappingKey[_extractable],
            ["encrypt"],
            wrappingKey[_algorithm],
            wrappingKey[_handle],
          ),
          bytes,
        );
      } else {
        throw new DOMException(
          "Algorithm not supported",
          "NotSupportedError",
        );
      }
    }
    
    async unwrapKey(
      format,
      wrappedKey,
      unwrappingKey,
      unwrapAlgorithm,
      unwrappedKeyAlgorithm,
      extractable,
      keyUsages,
    ) {
      webidl.assertBranded(this, SubtleCrypto);
      const prefix = "Failed to execute 'unwrapKey' on 'SubtleCrypto'";
      webidl.requiredArguments(arguments.length, 7, { prefix });
      format = webidl.converters.KeyFormat(format, {
        prefix,
        context: "Argument 1",
      });
      wrappedKey = webidl.converters.BufferSource(wrappedKey, {
        prefix,
        context: "Argument 2",
      });
      unwrappingKey = webidl.converters.CryptoKey(unwrappingKey, {
        prefix,
        context: "Argument 3",
      });
      unwrapAlgorithm = webidl.converters.AlgorithmIdentifier(unwrapAlgorithm, {
        prefix,
        context: "Argument 4",
      });
      unwrappedKeyAlgorithm = webidl.converters.AlgorithmIdentifier(
        unwrappedKeyAlgorithm,
        {
          prefix,
          context: "Argument 5",
        },
      );
      extractable = webidl.converters.boolean(extractable, {
        prefix,
        context: "Argument 6",
      });
      keyUsages = webidl.converters["sequence<KeyUsage>"](keyUsages, {
        prefix,
        context: "Argument 7",
      });
            wrappedKey = copyBuffer(wrappedKey);
      let normalizedAlgorithm;
      try {
                normalizedAlgorithm = normalizeAlgorithm(unwrapAlgorithm, "unwrapKey");
      } catch (_) {
                normalizedAlgorithm = normalizeAlgorithm(unwrapAlgorithm, "decrypt");
      }
            const normalizedKeyAlgorithm = normalizeAlgorithm(
        unwrappedKeyAlgorithm,
        "importKey",
      );
            if (normalizedAlgorithm.name !== unwrappingKey[_algorithm].name) {
        throw new DOMException(
          "Unwrapping algorithm doesn't match key algorithm.",
          "InvalidAccessError",
        );
      }
            if (!ArrayPrototypeIncludes(unwrappingKey[_usages], "unwrapKey")) {
        throw new DOMException(
          "Key does not support the 'unwrapKey' operation.",
          "InvalidAccessError",
        );
      }
            let key;
      if (
        supportedAlgorithms["unwrapKey"][normalizedAlgorithm.name] !== undefined
      ) {
        const handle = unwrappingKey[_handle];
        const keyData = WeakMapPrototypeGet(KEY_STORE, handle);
        switch (normalizedAlgorithm.name) {
          case "AES-KW": {
            const plainText = await core.opSync("op_crypto_unwrap_key", {
              key: keyData,
              algorithm: normalizedAlgorithm.name,
            }, wrappedKey);
                        key = plainText.buffer;
            break;
          }
          default: {
            throw new DOMException(
              "Not implemented",
              "NotSupportedError",
            );
          }
        }
      } else if (
        supportedAlgorithms["decrypt"][normalizedAlgorithm.name] !== undefined
      ) {
                key = await this.decrypt(
          normalizedAlgorithm,
          constructKey(
            unwrappingKey[_type],
            unwrappingKey[_extractable],
            ["decrypt"],
            unwrappingKey[_algorithm],
            unwrappingKey[_handle],
          ),
          wrappedKey,
        );
      } else {
        throw new DOMException(
          "Algorithm not supported",
          "NotSupportedError",
        );
      }
      let bytes;
            if (format !== "jwk") {
        bytes = key;
      } else {
        const utf8 = new TextDecoder("utf-8").decode(key);
        bytes = JSONParse(utf8);
      }
            const result = await this.importKey(
        format,
        bytes,
        normalizedKeyAlgorithm,
        extractable,
        keyUsages,
      );
            if (
        (result[_type] == "secret" || result[_type] == "private") &&
        keyUsages.length == 0
      ) {
        throw new SyntaxError("Invalid key type.");
      }
            result[_extractable] = extractable;
            result[_usages] = usageIntersection(keyUsages, recognisedUsages);
            return result;
    }
    
    async generateKey(algorithm, extractable, keyUsages) {
      webidl.assertBranded(this, SubtleCrypto);
      const prefix = "Failed to execute 'generateKey' on 'SubtleCrypto'";
      webidl.requiredArguments(arguments.length, 3, { prefix });
      algorithm = webidl.converters.AlgorithmIdentifier(algorithm, {
        prefix,
        context: "Argument 1",
      });
      extractable = webidl.converters["boolean"](extractable, {
        prefix,
        context: "Argument 2",
      });
      keyUsages = webidl.converters["sequence<KeyUsage>"](keyUsages, {
        prefix,
        context: "Argument 3",
      });
      const usages = keyUsages;
      const normalizedAlgorithm = normalizeAlgorithm(algorithm, "generateKey");
      const result = await generateKey(
        normalizedAlgorithm,
        extractable,
        usages,
      );
      if (result instanceof CryptoKey) {
        const type = result[_type];
        if ((type === "secret" || type === "private") && usages.length === 0) {
          throw new DOMException("Invalid key usages", "SyntaxError");
        }
      } else if (result.privateKey instanceof CryptoKey) {
        if (result.privateKey[_usages].length === 0) {
          throw new DOMException("Invalid key usages", "SyntaxError");
        }
      }
      return result;
    }
  }
  async function generateKey(normalizedAlgorithm, extractable, usages) {
    const algorithmName = normalizedAlgorithm.name;
    switch (algorithmName) {
      case "RSASSA-PKCS1-v1_5":
      case "RSA-PSS": {
                if (
          ArrayPrototypeFind(
            usages,
            (u) => !ArrayPrototypeIncludes(["sign", "verify"], u),
          ) !== undefined
        ) {
          throw new DOMException("Invalid key usages", "SyntaxError");
        }
                const keyData = await core.opAsync(
          "op_crypto_generate_key",
          {
            algorithm: "RSA",
            modulusLength: normalizedAlgorithm.modulusLength,
            publicExponent: normalizedAlgorithm.publicExponent,
          },
        );
        const handle = {};
        WeakMapPrototypeSet(KEY_STORE, handle, {
          type: "private",
          data: keyData,
        });
                const algorithm = {
          name: algorithmName,
          modulusLength: normalizedAlgorithm.modulusLength,
          publicExponent: normalizedAlgorithm.publicExponent,
          hash: normalizedAlgorithm.hash,
        };
                const publicKey = constructKey(
          "public",
          true,
          usageIntersection(usages, ["verify"]),
          algorithm,
          handle,
        );
                const privateKey = constructKey(
          "private",
          extractable,
          usageIntersection(usages, ["sign"]),
          algorithm,
          handle,
        );
                return { publicKey, privateKey };
      }
      case "RSA-OAEP": {
        if (
          ArrayPrototypeFind(
            usages,
            (u) =>
              !ArrayPrototypeIncludes([
                "encrypt",
                "decrypt",
                "wrapKey",
                "unwrapKey",
              ], u),
          ) !== undefined
        ) {
          throw new DOMException("Invalid key usages", "SyntaxError");
        }
                const keyData = await core.opAsync(
          "op_crypto_generate_key",
          {
            algorithm: "RSA",
            modulusLength: normalizedAlgorithm.modulusLength,
            publicExponent: normalizedAlgorithm.publicExponent,
          },
        );
        const handle = {};
        WeakMapPrototypeSet(KEY_STORE, handle, {
          type: "private",
          data: keyData,
        });
                const algorithm = {
          name: algorithmName,
          modulusLength: normalizedAlgorithm.modulusLength,
          publicExponent: normalizedAlgorithm.publicExponent,
          hash: normalizedAlgorithm.hash,
        };
                const publicKey = constructKey(
          "public",
          true,
          usageIntersection(usages, ["encrypt", "wrapKey"]),
          algorithm,
          handle,
        );
                const privateKey = constructKey(
          "private",
          extractable,
          usageIntersection(usages, ["decrypt", "unwrapKey"]),
          algorithm,
          handle,
        );
                return { publicKey, privateKey };
      }
      case "ECDSA": {
        const namedCurve = normalizedAlgorithm.namedCurve;
                if (
          ArrayPrototypeFind(
            usages,
            (u) => !ArrayPrototypeIncludes(["sign", "verify"], u),
          ) !== undefined
        ) {
          throw new DOMException("Invalid key usages", "SyntaxError");
        }
                const handle = {};
        if (
          ArrayPrototypeIncludes(
            supportedNamedCurves,
            namedCurve,
          )
        ) {
          const keyData = await core.opAsync("op_crypto_generate_key", {
            algorithm: "EC",
            namedCurve,
          });
          WeakMapPrototypeSet(KEY_STORE, handle, {
            type: "private",
            data: keyData,
          });
        } else {
          throw new DOMException("Curve not supported", "NotSupportedError");
        }
                const algorithm = {
          name: algorithmName,
          namedCurve,
        };
                const publicKey = constructKey(
          "public",
          true,
          usageIntersection(usages, ["verify"]),
          algorithm,
          handle,
        );
                const privateKey = constructKey(
          "private",
          extractable,
          usageIntersection(usages, ["sign"]),
          algorithm,
          handle,
        );
                return { publicKey, privateKey };
      }
      case "ECDH": {
        const namedCurve = normalizedAlgorithm.namedCurve;
                if (
          ArrayPrototypeFind(
            usages,
            (u) => !ArrayPrototypeIncludes(["deriveKey", "deriveBits"], u),
          ) !== undefined
        ) {
          throw new DOMException("Invalid key usages", "SyntaxError");
        }
                const handle = {};
        if (
          ArrayPrototypeIncludes(
            supportedNamedCurves,
            namedCurve,
          )
        ) {
          const keyData = await core.opAsync("op_crypto_generate_key", {
            algorithm: "EC",
            namedCurve,
          });
          WeakMapPrototypeSet(KEY_STORE, handle, {
            type: "private",
            data: keyData,
          });
        } else {
          throw new DOMException("Curve not supported", "NotSupportedError");
        }
                const algorithm = {
          name: algorithmName,
          namedCurve,
        };
                const publicKey = constructKey(
          "public",
          true,
          usageIntersection(usages, []),
          algorithm,
          handle,
        );
                const privateKey = constructKey(
          "private",
          extractable,
          usageIntersection(usages, ["deriveKey", "deriveBits"]),
          algorithm,
          handle,
        );
                return { publicKey, privateKey };
      }
      case "AES-CTR":
      case "AES-CBC":
      case "AES-GCM": {
                if (
          ArrayPrototypeFind(
            usages,
            (u) =>
              !ArrayPrototypeIncludes([
                "encrypt",
                "decrypt",
                "wrapKey",
                "unwrapKey",
              ], u),
          ) !== undefined
        ) {
          throw new DOMException("Invalid key usages", "SyntaxError");
        }
        return generateKeyAES(normalizedAlgorithm, extractable, usages);
      }
      case "AES-KW": {
                if (
          ArrayPrototypeFind(
            usages,
            (u) => !ArrayPrototypeIncludes(["wrapKey", "unwrapKey"], u),
          ) !== undefined
        ) {
          throw new DOMException("Invalid key usages", "SyntaxError");
        }
        return generateKeyAES(normalizedAlgorithm, extractable, usages);
      }
      case "HMAC": {
                if (
          ArrayPrototypeFind(
            usages,
            (u) => !ArrayPrototypeIncludes(["sign", "verify"], u),
          ) !== undefined
        ) {
          throw new DOMException("Invalid key usages", "SyntaxError");
        }
                let length;
        if (normalizedAlgorithm.length === undefined) {
          length = null;
        } else if (normalizedAlgorithm.length !== 0) {
          length = normalizedAlgorithm.length;
        } else {
          throw new DOMException("Invalid length", "OperationError");
        }
                const keyData = await core.opAsync("op_crypto_generate_key", {
          algorithm: "HMAC",
          hash: normalizedAlgorithm.hash.name,
          length,
        });
        const handle = {};
        WeakMapPrototypeSet(KEY_STORE, handle, {
          type: "secret",
          data: keyData,
        });
                const algorithm = {
          name: algorithmName,
          hash: {
            name: normalizedAlgorithm.hash.name,
          },
          length: keyData.byteLength * 8,
        };
                const key = constructKey(
          "secret",
          extractable,
          usages,
          algorithm,
          handle,
        );
                return key;
      }
    }
  }
  function exportKeyAES(
    format,
    key,
    innerKey,
  ) {
    switch (format) {
            case "raw": {
                const data = innerKey.data;
                return data.buffer;
      }
      case "jwk": {
                const jwk = {
          kty: "oct",
        };
                const data = core.opSync("op_crypto_export_key", {
          format: "jwksecret",
          algorithm: "AES",
        }, innerKey);
        ObjectAssign(jwk, data);
                const algorithm = key[_algorithm];
        switch (algorithm.length) {
          case 128:
            jwk.alg = aesJwkAlg[algorithm.name][128];
            break;
          case 192:
            jwk.alg = aesJwkAlg[algorithm.name][192];
            break;
          case 256:
            jwk.alg = aesJwkAlg[algorithm.name][256];
            break;
          default:
            throw new DOMException(
              "Invalid key length",
              "NotSupportedError",
            );
        }
                jwk.key_ops = key.usages;
                jwk.ext = key[_extractable];
                return jwk;
      }
      default:
        throw new DOMException("Not implemented", "NotSupportedError");
    }
  }
  function importKeyAES(
    format,
    normalizedAlgorithm,
    keyData,
    extractable,
    keyUsages,
    supportedKeyUsages,
  ) {
        if (
      ArrayPrototypeFind(
        keyUsages,
        (u) => !ArrayPrototypeIncludes(supportedKeyUsages, u),
      ) !== undefined
    ) {
      throw new DOMException("Invalid key usages", "SyntaxError");
    }
    const algorithmName = normalizedAlgorithm.name;
        let data = keyData;
    switch (format) {
      case "raw": {
                if (
          !ArrayPrototypeIncludes([128, 192, 256], keyData.byteLength * 8)
        ) {
          throw new DOMException("Invalid key length", "Datarror");
        }
        break;
      }
      case "jwk": {
                const jwk = keyData;
                if (jwk.kty !== "oct") {
          throw new DOMException(
            "'kty' property of JsonWebKey must be 'oct'",
            "DataError",
          );
        }
                if (jwk.k === undefined) {
          throw new DOMException(
            "'k' property of JsonWebKey must be present",
            "DataError",
          );
        }
                const { rawData } = core.opSync(
          "op_crypto_import_key",
          { algorithm: "AES" },
          { jwkSecret: jwk },
        );
        data = rawData.data;
                switch (data.byteLength * 8) {
          case 128:
            if (
              jwk.alg !== undefined &&
              jwk.alg !== aesJwkAlg[algorithmName][128]
            ) {
              throw new DOMException("Invalid algorithm", "DataError");
            }
            break;
          case 192:
            if (
              jwk.alg !== undefined &&
              jwk.alg !== aesJwkAlg[algorithmName][192]
            ) {
              throw new DOMException("Invalid algorithm", "DataError");
            }
            break;
          case 256:
            if (
              jwk.alg !== undefined &&
              jwk.alg !== aesJwkAlg[algorithmName][256]
            ) {
              throw new DOMException("Invalid algorithm", "DataError");
            }
            break;
          default:
            throw new DOMException(
              "Invalid key length",
              "DataError",
            );
        }
                if (
          keyUsages.length > 0 && jwk.use !== undefined && jwk.use !== "enc"
        ) {
          throw new DOMException("Invalid key usages", "DataError");
        }
                        if (jwk.key_ops !== undefined) {
          if (
            ArrayPrototypeFind(
              jwk.key_ops,
              (u) => !ArrayPrototypeIncludes(recognisedUsages, u),
            ) !== undefined
          ) {
            throw new DOMException(
              "'key_ops' property of JsonWebKey is invalid",
              "DataError",
            );
          }
          if (
            !ArrayPrototypeEvery(
              jwk.key_ops,
              (u) => ArrayPrototypeIncludes(keyUsages, u),
            )
          ) {
            throw new DOMException(
              "'key_ops' property of JsonWebKey is invalid",
              "DataError",
            );
          }
        }
                if (jwk.ext === false && extractable === true) {
          throw new DOMException(
            "'ext' property of JsonWebKey must not be false if extractable is true",
            "DataError",
          );
        }
        break;
      }
      default:
        throw new DOMException("Not implemented", "NotSupportedError");
    }
    const handle = {};
    WeakMapPrototypeSet(KEY_STORE, handle, {
      type: "secret",
      data,
    });
        const algorithm = {
      name: algorithmName,
      length: data.byteLength * 8,
    };
    const key = constructKey(
      "secret",
      extractable,
      usageIntersection(keyUsages, recognisedUsages),
      algorithm,
      handle,
    );
        return key;
  }
  function importKeyHMAC(
    format,
    normalizedAlgorithm,
    keyData,
    extractable,
    keyUsages,
  ) {
        if (
      ArrayPrototypeFind(
        keyUsages,
        (u) => !ArrayPrototypeIncludes(["sign", "verify"], u),
      ) !== undefined
    ) {
      throw new DOMException("Invalid key usages", "SyntaxError");
    }
        let hash;
    let data;
        switch (format) {
      case "raw": {
        data = keyData;
        hash = normalizedAlgorithm.hash;
        break;
      }
      case "jwk": {
        const jwk = keyData;
                if (jwk.kty !== "oct") {
          throw new DOMException(
            "'kty' property of JsonWebKey must be 'oct'",
            "DataError",
          );
        }
                if (jwk.k === undefined) {
          throw new DOMException(
            "'k' property of JsonWebKey must be present",
            "DataError",
          );
        }
                const { rawData } = core.opSync(
          "op_crypto_import_key",
          { algorithm: "HMAC" },
          { jwkSecret: jwk },
        );
        data = rawData.data;
                hash = normalizedAlgorithm.hash;
                switch (hash.name) {
          case "SHA-1": {
            if (jwk.alg !== undefined && jwk.alg !== "HS1") {
              throw new DOMException(
                "'alg' property of JsonWebKey must be 'HS1'",
                "DataError",
              );
            }
            break;
          }
          case "SHA-256": {
            if (jwk.alg !== undefined && jwk.alg !== "HS256") {
              throw new DOMException(
                "'alg' property of JsonWebKey must be 'HS256'",
                "DataError",
              );
            }
            break;
          }
          case "SHA-384": {
            if (jwk.alg !== undefined && jwk.alg !== "HS384") {
              throw new DOMException(
                "'alg' property of JsonWebKey must be 'HS384'",
                "DataError",
              );
            }
            break;
          }
          case "SHA-512": {
            if (jwk.alg !== undefined && jwk.alg !== "HS512") {
              throw new DOMException(
                "'alg' property of JsonWebKey must be 'HS512'",
                "DataError",
              );
            }
            break;
          }
          default:
            throw new TypeError("unreachable");
        }
                if (
          keyUsages.length > 0 && jwk.use !== undefined && jwk.use !== "sign"
        ) {
          throw new DOMException(
            "'use' property of JsonWebKey must be 'sign'",
            "DataError",
          );
        }
                        if (jwk.key_ops !== undefined) {
          if (
            ArrayPrototypeFind(
              jwk.key_ops,
              (u) => !ArrayPrototypeIncludes(recognisedUsages, u),
            ) !== undefined
          ) {
            throw new DOMException(
              "'key_ops' property of JsonWebKey is invalid",
              "DataError",
            );
          }
          if (
            !ArrayPrototypeEvery(
              jwk.key_ops,
              (u) => ArrayPrototypeIncludes(keyUsages, u),
            )
          ) {
            throw new DOMException(
              "'key_ops' property of JsonWebKey is invalid",
              "DataError",
            );
          }
        }
                if (jwk.ext === false && extractable === true) {
          throw new DOMException(
            "'ext' property of JsonWebKey must not be false if extractable is true",
            "DataError",
          );
        }
        break;
      }
      default:
        throw new DOMException("Not implemented", "NotSupportedError");
    }
        let length = data.byteLength * 8;
        if (length === 0) {
      throw new DOMException("Key length is zero", "DataError");
    }
        if (normalizedAlgorithm.length !== undefined) {
      if (
        normalizedAlgorithm.length > length ||
        normalizedAlgorithm.length <= (length - 8)
      ) {
        throw new DOMException(
          "Key length is invalid",
          "DataError",
        );
      }
      length = normalizedAlgorithm.length;
    }
    const handle = {};
    WeakMapPrototypeSet(KEY_STORE, handle, {
      type: "secret",
      data,
    });
    const algorithm = {
      name: "HMAC",
      length,
      hash,
    };
    const key = constructKey(
      "secret",
      extractable,
      usageIntersection(keyUsages, recognisedUsages),
      algorithm,
      handle,
    );
    return key;
  }
  function importKeyEC(
    format,
    normalizedAlgorithm,
    keyData,
    extractable,
    keyUsages,
  ) {
    const supportedUsages = SUPPORTED_KEY_USAGES[normalizedAlgorithm.name];
    switch (format) {
      case "raw": {
                if (
          !ArrayPrototypeIncludes(
            supportedNamedCurves,
            normalizedAlgorithm.namedCurve,
          )
        ) {
          throw new DOMException(
            "Invalid namedCurve",
            "DataError",
          );
        }
                if (
          ArrayPrototypeFind(
            keyUsages,
            (u) =>
              !ArrayPrototypeIncludes(
                SUPPORTED_KEY_USAGES[normalizedAlgorithm.name].public,
                u,
              ),
          ) !== undefined
        ) {
          throw new DOMException("Invalid key usages", "SyntaxError");
        }
                const { rawData } = core.opSync("op_crypto_import_key", {
          algorithm: normalizedAlgorithm.name,
          namedCurve: normalizedAlgorithm.namedCurve,
        }, { raw: keyData });
        const handle = {};
        WeakMapPrototypeSet(KEY_STORE, handle, rawData);
                const algorithm = {
          name: normalizedAlgorithm.name,
          namedCurve: normalizedAlgorithm.namedCurve,
        };
                const key = constructKey(
          "public",
          extractable,
          usageIntersection(keyUsages, recognisedUsages),
          algorithm,
          handle,
        );
        return key;
      }
      case "pkcs8": {
                if (
          ArrayPrototypeFind(
            keyUsages,
            (u) =>
              !ArrayPrototypeIncludes(
                SUPPORTED_KEY_USAGES[normalizedAlgorithm.name].private,
                u,
              ),
          ) !== undefined
        ) {
          throw new DOMException("Invalid key usages", "SyntaxError");
        }
                const { rawData } = core.opSync("op_crypto_import_key", {
          algorithm: normalizedAlgorithm.name,
          namedCurve: normalizedAlgorithm.namedCurve,
        }, { pkcs8: keyData });
        const handle = {};
        WeakMapPrototypeSet(KEY_STORE, handle, rawData);
        const algorithm = {
          name: normalizedAlgorithm.name,
          namedCurve: normalizedAlgorithm.namedCurve,
        };
        const key = constructKey(
          "private",
          extractable,
          usageIntersection(keyUsages, recognisedUsages),
          algorithm,
          handle,
        );
        return key;
      }
      case "spki": {
                if (normalizedAlgorithm.name == "ECDSA") {
          if (
            ArrayPrototypeFind(
              keyUsages,
              (u) =>
                !ArrayPrototypeIncludes(
                  SUPPORTED_KEY_USAGES[normalizedAlgorithm.name].public,
                  u,
                ),
            ) !== undefined
          ) {
            throw new DOMException("Invalid key usages", "SyntaxError");
          }
        } else if (keyUsages.length != 0) {
          throw new DOMException("Key usage must be empty", "SyntaxError");
        }
                const { rawData } = core.opSync("op_crypto_import_key", {
          algorithm: normalizedAlgorithm.name,
          namedCurve: normalizedAlgorithm.namedCurve,
        }, { spki: keyData });
        const handle = {};
        WeakMapPrototypeSet(KEY_STORE, handle, rawData);
        const algorithm = {
          name: normalizedAlgorithm.name,
          namedCurve: normalizedAlgorithm.namedCurve,
        };
                const key = constructKey(
          "public",
          extractable,
          usageIntersection(keyUsages, recognisedUsages),
          algorithm,
          handle,
        );
        return key;
      }
      case "jwk": {
        const jwk = keyData;
        const keyType = (jwk.d !== undefined) ? "private" : "public";
                if (
          ArrayPrototypeFind(
            keyUsages,
            (u) => !ArrayPrototypeIncludes(supportedUsages[keyType], u),
          ) !== undefined
        ) {
          throw new DOMException("Invalid key usages", "SyntaxError");
        }
                if (jwk.kty !== "EC") {
          throw new DOMException(
            "'kty' property of JsonWebKey must be 'EC'",
            "DataError",
          );
        }
                if (
          keyUsages.length > 0 && jwk.use !== undefined &&
          jwk.use !== supportedUsages.jwkUse
        ) {
          throw new DOMException(
            `'use' property of JsonWebKey must be '${supportedUsages.jwkUse}'`,
            "DataError",
          );
        }
                        if (jwk.key_ops !== undefined) {
          if (
            ArrayPrototypeFind(
              jwk.key_ops,
              (u) => !ArrayPrototypeIncludes(recognisedUsages, u),
            ) !== undefined
          ) {
            throw new DOMException(
              "'key_ops' member of JsonWebKey is invalid",
              "DataError",
            );
          }
          if (
            !ArrayPrototypeEvery(
              jwk.key_ops,
              (u) => ArrayPrototypeIncludes(keyUsages, u),
            )
          ) {
            throw new DOMException(
              "'key_ops' member of JsonWebKey is invalid",
              "DataError",
            );
          }
        }
                if (jwk.ext === false && extractable === true) {
          throw new DOMException(
            "'ext' property of JsonWebKey must not be false if extractable is true",
            "DataError",
          );
        }
                if (jwk.alg !== undefined && normalizedAlgorithm.name == "ECDSA") {
          let algNamedCurve;
          switch (jwk.alg) {
            case "ES256": {
              algNamedCurve = "P-256";
              break;
            }
            case "ES384": {
              algNamedCurve = "P-384";
              break;
            }
            case "ES512": {
              algNamedCurve = "P-521";
              break;
            }
            default:
              throw new DOMException(
                "Curve algorithm not supported",
                "DataError",
              );
          }
          if (algNamedCurve) {
            if (algNamedCurve !== normalizedAlgorithm.namedCurve) {
              throw new DOMException(
                "Mismatched curve algorithm",
                "DataError",
              );
            }
          }
        }
                if (jwk.x === undefined) {
          throw new DOMException(
            "'x' property of JsonWebKey is required for EC keys",
            "DataError",
          );
        }
        if (jwk.y === undefined) {
          throw new DOMException(
            "'y' property of JsonWebKey is required for EC keys",
            "DataError",
          );
        }
        if (jwk.d !== undefined) {
                    const { rawData } = core.opSync("op_crypto_import_key", {
            algorithm: normalizedAlgorithm.name,
            namedCurve: normalizedAlgorithm.namedCurve,
          }, { jwkPrivateEc: jwk });
          const handle = {};
          WeakMapPrototypeSet(KEY_STORE, handle, rawData);
          const algorithm = {
            name: normalizedAlgorithm.name,
            namedCurve: normalizedAlgorithm.namedCurve,
          };
          const key = constructKey(
            "private",
            extractable,
            usageIntersection(keyUsages, recognisedUsages),
            algorithm,
            handle,
          );
          return key;
        } else {
          const { rawData } = core.opSync("op_crypto_import_key", {
            algorithm: normalizedAlgorithm.name,
            namedCurve: normalizedAlgorithm.namedCurve,
          }, { jwkPublicEc: jwk });
          const handle = {};
          WeakMapPrototypeSet(KEY_STORE, handle, rawData);
          const algorithm = {
            name: normalizedAlgorithm.name,
            namedCurve: normalizedAlgorithm.namedCurve,
          };
          const key = constructKey(
            "public",
            extractable,
            usageIntersection(keyUsages, recognisedUsages),
            algorithm,
            handle,
          );
          return key;
        }
      }
      default:
        throw new DOMException("Not implemented", "NotSupportedError");
    }
  }
  const SUPPORTED_KEY_USAGES = {
    "RSASSA-PKCS1-v1_5": {
      public: ["verify"],
      private: ["sign"],
      jwtUse: "sig",
    },
    "RSA-PSS": {
      public: ["verify"],
      private: ["sign"],
      jwtUse: "sig",
    },
    "RSA-OAEP": {
      public: ["encrypt", "wrapKey"],
      private: ["decrypt", "unwrapKey"],
      jwtUse: "enc",
    },
    "ECDSA": {
      public: ["verify"],
      private: ["sign"],
      jwtUse: "sig",
    },
    "ECDH": {
      public: [],
      private: ["deriveKey", "deriveBits"],
      jwtUse: "enc",
    },
  };
  function importKeyRSA(
    format,
    normalizedAlgorithm,
    keyData,
    extractable,
    keyUsages,
  ) {
    switch (format) {
      case "pkcs8": {
                if (
          ArrayPrototypeFind(
            keyUsages,
            (u) =>
              !ArrayPrototypeIncludes(
                SUPPORTED_KEY_USAGES[normalizedAlgorithm.name].private,
                u,
              ),
          ) !== undefined
        ) {
          throw new DOMException("Invalid key usages", "SyntaxError");
        }
                const { modulusLength, publicExponent, rawData } = core.opSync(
          "op_crypto_import_key",
          {
            algorithm: normalizedAlgorithm.name,
                        hash: normalizedAlgorithm.hash.name,
          },
          { pkcs8: keyData },
        );
        const handle = {};
        WeakMapPrototypeSet(KEY_STORE, handle, rawData);
        const algorithm = {
          name: normalizedAlgorithm.name,
          modulusLength,
          publicExponent,
          hash: normalizedAlgorithm.hash,
        };
        const key = constructKey(
          "private",
          extractable,
          usageIntersection(keyUsages, recognisedUsages),
          algorithm,
          handle,
        );
        return key;
      }
      case "spki": {
                if (
          ArrayPrototypeFind(
            keyUsages,
            (u) =>
              !ArrayPrototypeIncludes(
                SUPPORTED_KEY_USAGES[normalizedAlgorithm.name].public,
                u,
              ),
          ) !== undefined
        ) {
          throw new DOMException("Invalid key usages", "SyntaxError");
        }
                const { modulusLength, publicExponent, rawData } = core.opSync(
          "op_crypto_import_key",
          {
            algorithm: normalizedAlgorithm.name,
                        hash: normalizedAlgorithm.hash.name,
          },
          { spki: keyData },
        );
        const handle = {};
        WeakMapPrototypeSet(KEY_STORE, handle, rawData);
        const algorithm = {
          name: normalizedAlgorithm.name,
          modulusLength,
          publicExponent,
          hash: normalizedAlgorithm.hash,
        };
        const key = constructKey(
          "public",
          extractable,
          usageIntersection(keyUsages, recognisedUsages),
          algorithm,
          handle,
        );
        return key;
      }
      case "jwk": {
                const jwk = keyData;
                if (jwk.d !== undefined) {
          if (
            ArrayPrototypeFind(
              keyUsages,
              (u) =>
                !ArrayPrototypeIncludes(
                  SUPPORTED_KEY_USAGES[normalizedAlgorithm.name].private,
                  u,
                ),
            ) !== undefined
          ) {
            throw new DOMException("Invalid key usages", "SyntaxError");
          }
        } else if (
          ArrayPrototypeFind(
            keyUsages,
            (u) =>
              !ArrayPrototypeIncludes(
                SUPPORTED_KEY_USAGES[normalizedAlgorithm.name].public,
                u,
              ),
          ) !== undefined
        ) {
          throw new DOMException("Invalid key usages", "SyntaxError");
        }
                if (StringPrototypeToUpperCase(jwk.kty) !== "RSA") {
          throw new DOMException(
            "'kty' property of JsonWebKey must be 'RSA'",
            "DataError",
          );
        }
                if (
          keyUsages.length > 0 && jwk.use !== undefined &&
          StringPrototypeToLowerCase(jwk.use) !==
            SUPPORTED_KEY_USAGES[normalizedAlgorithm.name].jwtUse
        ) {
          throw new DOMException(
            `'use' property of JsonWebKey must be '${
              SUPPORTED_KEY_USAGES[normalizedAlgorithm.name].jwtUse
            }'`,
            "DataError",
          );
        }
                if (jwk.key_ops !== undefined) {
          if (
            ArrayPrototypeFind(
              jwk.key_ops,
              (u) => !ArrayPrototypeIncludes(recognisedUsages, u),
            ) !== undefined
          ) {
            throw new DOMException(
              "'key_ops' property of JsonWebKey is invalid",
              "DataError",
            );
          }
          if (
            !ArrayPrototypeEvery(
              jwk.key_ops,
              (u) => ArrayPrototypeIncludes(keyUsages, u),
            )
          ) {
            throw new DOMException(
              "'key_ops' property of JsonWebKey is invalid",
              "DataError",
            );
          }
        }
        if (jwk.ext === false && extractable === true) {
          throw new DOMException(
            "'ext' property of JsonWebKey must not be false if extractable is true",
            "DataError",
          );
        }
                let hash;
                if (normalizedAlgorithm.name === "RSASSA-PKCS1-v1_5") {
          switch (jwk.alg) {
            case undefined:
              hash = undefined;
              break;
            case "RS1":
              hash = "SHA-1";
              break;
            case "RS256":
              hash = "SHA-256";
              break;
            case "RS384":
              hash = "SHA-384";
              break;
            case "RS512":
              hash = "SHA-512";
              break;
            default:
              throw new DOMException(
                `'alg' property of JsonWebKey must be one of 'RS1', 'RS256', 'RS384', 'RS512'`,
                "DataError",
              );
          }
        } else if (normalizedAlgorithm.name === "RSA-PSS") {
          switch (jwk.alg) {
            case undefined:
              hash = undefined;
              break;
            case "PS1":
              hash = "SHA-1";
              break;
            case "PS256":
              hash = "SHA-256";
              break;
            case "PS384":
              hash = "SHA-384";
              break;
            case "PS512":
              hash = "SHA-512";
              break;
            default:
              throw new DOMException(
                `'alg' property of JsonWebKey must be one of 'PS1', 'PS256', 'PS384', 'PS512'`,
                "DataError",
              );
          }
        } else {
          switch (jwk.alg) {
            case undefined:
              hash = undefined;
              break;
            case "RSA-OAEP":
              hash = "SHA-1";
              break;
            case "RSA-OAEP-256":
              hash = "SHA-256";
              break;
            case "RSA-OAEP-384":
              hash = "SHA-384";
              break;
            case "RSA-OAEP-512":
              hash = "SHA-512";
              break;
            default:
              throw new DOMException(
                `'alg' property of JsonWebKey must be one of 'RSA-OAEP', 'RSA-OAEP-256', 'RSA-OAEP-384', or 'RSA-OAEP-512'`,
                "DataError",
              );
          }
        }
                if (hash !== undefined) {
                    const normalizedHash = normalizeAlgorithm(hash, "digest");
                    if (normalizedHash.name !== normalizedAlgorithm.hash.name) {
            throw new DOMException(
              `'alg' property of JsonWebKey must be '${normalizedAlgorithm.name}'`,
              "DataError",
            );
          }
        }
                if (jwk.d !== undefined) {
                    const optimizationsPresent = jwk.p !== undefined ||
            jwk.q !== undefined || jwk.dp !== undefined ||
            jwk.dq !== undefined || jwk.qi !== undefined;
          if (optimizationsPresent) {
            if (jwk.q === undefined) {
              throw new DOMException(
                "'q' property of JsonWebKey is required for private keys",
                "DataError",
              );
            }
            if (jwk.dp === undefined) {
              throw new DOMException(
                "'dp' property of JsonWebKey is required for private keys",
                "DataError",
              );
            }
            if (jwk.dq === undefined) {
              throw new DOMException(
                "'dq' property of JsonWebKey is required for private keys",
                "DataError",
              );
            }
            if (jwk.qi === undefined) {
              throw new DOMException(
                "'qi' property of JsonWebKey is required for private keys",
                "DataError",
              );
            }
            if (jwk.oth !== undefined) {
              throw new DOMException(
                "'oth' property of JsonWebKey is not supported",
                "NotSupportedError",
              );
            }
          } else {
            throw new DOMException(
              "only optimized private keys are supported",
              "NotSupportedError",
            );
          }
          const { modulusLength, publicExponent, rawData } = core.opSync(
            "op_crypto_import_key",
            {
              algorithm: normalizedAlgorithm.name,
              hash: normalizedAlgorithm.hash.name,
            },
            { jwkPrivateRsa: jwk },
          );
          const handle = {};
          WeakMapPrototypeSet(KEY_STORE, handle, rawData);
          const algorithm = {
            name: normalizedAlgorithm.name,
            modulusLength,
            publicExponent,
            hash: normalizedAlgorithm.hash,
          };
          const key = constructKey(
            "private",
            extractable,
            usageIntersection(keyUsages, recognisedUsages),
            algorithm,
            handle,
          );
          return key;
        } else {
                    if (jwk.n === undefined) {
            throw new DOMException(
              "'n' property of JsonWebKey is required for public keys",
              "DataError",
            );
          }
          if (jwk.e === undefined) {
            throw new DOMException(
              "'e' property of JsonWebKey is required for public keys",
              "DataError",
            );
          }
          const { modulusLength, publicExponent, rawData } = core.opSync(
            "op_crypto_import_key",
            {
              algorithm: normalizedAlgorithm.name,
              hash: normalizedAlgorithm.hash.name,
            },
            { jwkPublicRsa: jwk },
          );
          const handle = {};
          WeakMapPrototypeSet(KEY_STORE, handle, rawData);
          const algorithm = {
            name: normalizedAlgorithm.name,
            modulusLength,
            publicExponent,
            hash: normalizedAlgorithm.hash,
          };
          const key = constructKey(
            "public",
            extractable,
            usageIntersection(keyUsages, recognisedUsages),
            algorithm,
            handle,
          );
          return key;
        }
      }
      default:
        throw new DOMException("Not implemented", "NotSupportedError");
    }
  }
  function importKeyHKDF(
    format,
    keyData,
    extractable,
    keyUsages,
  ) {
    if (format !== "raw") {
      throw new DOMException("Format not supported", "NotSupportedError");
    }
        if (
      ArrayPrototypeFind(
        keyUsages,
        (u) => !ArrayPrototypeIncludes(["deriveKey", "deriveBits"], u),
      ) !== undefined
    ) {
      throw new DOMException("Invalid key usages", "SyntaxError");
    }
        if (extractable !== false) {
      throw new DOMException(
        "Key must not be extractable",
        "SyntaxError",
      );
    }
        const handle = {};
    WeakMapPrototypeSet(KEY_STORE, handle, {
      type: "secret",
      data: keyData,
    });
        const algorithm = {
      name: "HKDF",
    };
    const key = constructKey(
      "secret",
      false,
      usageIntersection(keyUsages, recognisedUsages),
      algorithm,
      handle,
    );
        return key;
  }
  function importKeyPBKDF2(
    format,
    keyData,
    extractable,
    keyUsages,
  ) {
        if (format !== "raw") {
      throw new DOMException("Format not supported", "NotSupportedError");
    }
        if (
      ArrayPrototypeFind(
        keyUsages,
        (u) => !ArrayPrototypeIncludes(["deriveKey", "deriveBits"], u),
      ) !== undefined
    ) {
      throw new DOMException("Invalid key usages", "SyntaxError");
    }
        if (extractable !== false) {
      throw new DOMException(
        "Key must not be extractable",
        "SyntaxError",
      );
    }
        const handle = {};
    WeakMapPrototypeSet(KEY_STORE, handle, {
      type: "secret",
      data: keyData,
    });
        const algorithm = {
      name: "PBKDF2",
    };
    const key = constructKey(
      "secret",
      false,
      usageIntersection(keyUsages, recognisedUsages),
      algorithm,
      handle,
    );
        return key;
  }
  function exportKeyHMAC(format, key, innerKey) {
        if (innerKey == null) {
      throw new DOMException("Key is not available", "OperationError");
    }
    switch (format) {
            case "raw": {
        const bits = innerKey.data;
        for (let _i = 7 & (8 - bits.length % 8); _i > 0; _i--) {
          bits.push(0);
        }
                return bits.buffer;
      }
      case "jwk": {
                const jwk = {
          kty: "oct",
        };
                const data = core.opSync("op_crypto_export_key", {
          format: "jwksecret",
          algorithm: key[_algorithm].name,
        }, innerKey);
        jwk.k = data.k;
                const algorithm = key[_algorithm];
                const hash = algorithm.hash;
                switch (hash.name) {
          case "SHA-1":
            jwk.alg = "HS1";
            break;
          case "SHA-256":
            jwk.alg = "HS256";
            break;
          case "SHA-384":
            jwk.alg = "HS384";
            break;
          case "SHA-512":
            jwk.alg = "HS512";
            break;
          default:
            throw new DOMException(
              "Hash algorithm not supported",
              "NotSupportedError",
            );
        }
                jwk.key_ops = key.usages;
                jwk.ext = key[_extractable];
                return jwk;
      }
      default:
        throw new DOMException("Not implemented", "NotSupportedError");
    }
  }
  function exportKeyRSA(format, key, innerKey) {
    switch (format) {
      case "pkcs8": {
                if (key[_type] !== "private") {
          throw new DOMException(
            "Key is not a private key",
            "InvalidAccessError",
          );
        }
                const data = core.opSync("op_crypto_export_key", {
          algorithm: key[_algorithm].name,
          format: "pkcs8",
        }, innerKey);
                return data.buffer;
      }
      case "spki": {
                if (key[_type] !== "public") {
          throw new DOMException(
            "Key is not a public key",
            "InvalidAccessError",
          );
        }
                const data = core.opSync("op_crypto_export_key", {
          algorithm: key[_algorithm].name,
          format: "spki",
        }, innerKey);
                return data.buffer;
      }
      case "jwk": {
                const jwk = {
          kty: "RSA",
        };
                const hash = key[_algorithm].hash.name;
                if (key[_algorithm].name === "RSASSA-PKCS1-v1_5") {
          switch (hash) {
            case "SHA-1":
              jwk.alg = "RS1";
              break;
            case "SHA-256":
              jwk.alg = "RS256";
              break;
            case "SHA-384":
              jwk.alg = "RS384";
              break;
            case "SHA-512":
              jwk.alg = "RS512";
              break;
            default:
              throw new DOMException(
                "Hash algorithm not supported",
                "NotSupportedError",
              );
          }
        } else if (key[_algorithm].name === "RSA-PSS") {
          switch (hash) {
            case "SHA-1":
              jwk.alg = "PS1";
              break;
            case "SHA-256":
              jwk.alg = "PS256";
              break;
            case "SHA-384":
              jwk.alg = "PS384";
              break;
            case "SHA-512":
              jwk.alg = "PS512";
              break;
            default:
              throw new DOMException(
                "Hash algorithm not supported",
                "NotSupportedError",
              );
          }
        } else {
          switch (hash) {
            case "SHA-1":
              jwk.alg = "RSA-OAEP";
              break;
            case "SHA-256":
              jwk.alg = "RSA-OAEP-256";
              break;
            case "SHA-384":
              jwk.alg = "RSA-OAEP-384";
              break;
            case "SHA-512":
              jwk.alg = "RSA-OAEP-512";
              break;
            default:
              throw new DOMException(
                "Hash algorithm not supported",
                "NotSupportedError",
              );
          }
        }
                const data = core.opSync("op_crypto_export_key", {
          format: key[_type] === "private" ? "jwkprivate" : "jwkpublic",
          algorithm: key[_algorithm].name,
        }, innerKey);
        ObjectAssign(jwk, data);
                jwk.key_ops = key.usages;
                jwk.ext = key[_extractable];
        return jwk;
      }
      default:
        throw new DOMException("Not implemented", "NotSupportedError");
    }
  }
  function exportKeyEC(format, key, innerKey) {
    switch (format) {
      case "pkcs8": {
                if (key[_type] !== "private") {
          throw new DOMException(
            "Key is not a private key",
            "InvalidAccessError",
          );
        }
                const data = core.opSync("op_crypto_export_key", {
          algorithm: key[_algorithm].name,
          namedCurve: key[_algorithm].namedCurve,
          format: "pkcs8",
        }, innerKey);
        return data.buffer;
      }
      case "spki": {
                if (key[_type] !== "public") {
          throw new DOMException(
            "Key is not a public key",
            "InvalidAccessError",
          );
        }
                const data = core.opSync("op_crypto_export_key", {
          algorithm: key[_algorithm].name,
          namedCurve: key[_algorithm].namedCurve,
          format: "spki",
        }, innerKey);
        return data.buffer;
      }
      case "jwk": {
        if (key[_algorithm].name == "ECDSA") {
                    const jwk = {
            kty: "EC",
          };
                    jwk.crv = key[_algorithm].namedCurve;
                    let algNamedCurve;
          switch (key[_algorithm].namedCurve) {
            case "P-256": {
              algNamedCurve = "ES256";
              break;
            }
            case "P-384": {
              algNamedCurve = "ES384";
              break;
            }
            case "P-521": {
              algNamedCurve = "ES512";
              break;
            }
            default:
              throw new DOMException(
                "Curve algorithm not supported",
                "DataError",
              );
          }
          jwk.alg = algNamedCurve;
                    const data = core.opSync("op_crypto_export_key", {
            format: key[_type] === "private" ? "jwkprivate" : "jwkpublic",
            algorithm: key[_algorithm].name,
            namedCurve: key[_algorithm].namedCurve,
          }, innerKey);
          ObjectAssign(jwk, data);
                    jwk.key_ops = key.usages;
                    jwk.ext = key[_extractable];
          return jwk;
        } else {                     const jwk = {
            kty: "EC",
          };
                    jwk.alg = "ECDH";
                    jwk.crv = key[_algorithm].namedCurve;
                    const data = core.opSync("op_crypto_export_key", {
            format: key[_type] === "private" ? "jwkprivate" : "jwkpublic",
            algorithm: key[_algorithm].name,
            namedCurve: key[_algorithm].namedCurve,
          }, innerKey);
          ObjectAssign(jwk, data);
                    jwk.key_ops = key.usages;
                    jwk.ext = key[_extractable];
          return jwk;
        }
      }
      default:
        throw new DOMException("Not implemented", "NotSupportedError");
    }
  }
  async function generateKeyAES(normalizedAlgorithm, extractable, usages) {
    const algorithmName = normalizedAlgorithm.name;
        if (!ArrayPrototypeIncludes([128, 192, 256], normalizedAlgorithm.length)) {
      throw new DOMException("Invalid key length", "OperationError");
    }
        const keyData = await core.opAsync("op_crypto_generate_key", {
      algorithm: "AES",
      length: normalizedAlgorithm.length,
    });
    const handle = {};
    WeakMapPrototypeSet(KEY_STORE, handle, {
      type: "secret",
      data: keyData,
    });
        const algorithm = {
      name: algorithmName,
      length: normalizedAlgorithm.length,
    };
        const key = constructKey(
      "secret",
      extractable,
      usages,
      algorithm,
      handle,
    );
        return key;
  }
  async function deriveBits(normalizedAlgorithm, baseKey, length) {
    switch (normalizedAlgorithm.name) {
      case "PBKDF2": {
                if (length == null || length == 0 || length % 8 !== 0) {
          throw new DOMException("Invalid length", "OperationError");
        }
        if (normalizedAlgorithm.iterations == 0) {
          throw new DOMException(
            "iterations must not be zero",
            "OperationError",
          );
        }
        const handle = baseKey[_handle];
        const keyData = WeakMapPrototypeGet(KEY_STORE, handle);
        normalizedAlgorithm.salt = copyBuffer(normalizedAlgorithm.salt);
        const buf = await core.opAsync("op_crypto_derive_bits", {
          key: keyData,
          algorithm: "PBKDF2",
          hash: normalizedAlgorithm.hash.name,
          iterations: normalizedAlgorithm.iterations,
          length,
        }, normalizedAlgorithm.salt);
        return buf.buffer;
      }
      case "ECDH": {
                if (baseKey[_type] !== "private") {
          throw new DOMException("Invalid key type", "InvalidAccessError");
        }
                const publicKey = normalizedAlgorithm.public;
                if (publicKey[_type] !== "public") {
          throw new DOMException("Invalid key type", "InvalidAccessError");
        }
                if (publicKey[_algorithm].name !== baseKey[_algorithm].name) {
          throw new DOMException(
            "Algorithm mismatch",
            "InvalidAccessError",
          );
        }
                if (
          publicKey[_algorithm].namedCurve !== baseKey[_algorithm].namedCurve
        ) {
          throw new DOMException(
            "namedCurve mismatch",
            "InvalidAccessError",
          );
        }
                if (
          ArrayPrototypeIncludes(
            supportedNamedCurves,
            publicKey[_algorithm].namedCurve,
          )
        ) {
          const baseKeyhandle = baseKey[_handle];
          const baseKeyData = WeakMapPrototypeGet(KEY_STORE, baseKeyhandle);
          const publicKeyhandle = publicKey[_handle];
          const publicKeyData = WeakMapPrototypeGet(KEY_STORE, publicKeyhandle);
          const buf = await core.opAsync("op_crypto_derive_bits", {
            key: baseKeyData,
            publicKey: publicKeyData,
            algorithm: "ECDH",
            namedCurve: publicKey[_algorithm].namedCurve,
            length,
          });
          return buf.buffer;
        } else {
          throw new DOMException("Not implemented", "NotSupportedError");
        }
      }
      case "HKDF": {
                if (length === null || length === 0 || length % 8 !== 0) {
          throw new DOMException("Invalid length", "OperationError");
        }
        const handle = baseKey[_handle];
        const keyDerivationKey = WeakMapPrototypeGet(KEY_STORE, handle);
        normalizedAlgorithm.salt = copyBuffer(normalizedAlgorithm.salt);
        normalizedAlgorithm.info = copyBuffer(normalizedAlgorithm.info);
        const buf = await core.opAsync("op_crypto_derive_bits", {
          key: keyDerivationKey,
          algorithm: "HKDF",
          hash: normalizedAlgorithm.hash.name,
          info: normalizedAlgorithm.info,
          length,
        }, normalizedAlgorithm.salt);
        return buf.buffer;
      }
      default:
        throw new DOMException("Not implemented", "NotSupportedError");
    }
  }
  async function encrypt(normalizedAlgorithm, key, data) {
    const handle = key[_handle];
    const keyData = WeakMapPrototypeGet(KEY_STORE, handle);
    switch (normalizedAlgorithm.name) {
      case "RSA-OAEP": {
                if (key[_type] !== "public") {
          throw new DOMException(
            "Key type not supported",
            "InvalidAccessError",
          );
        }
                if (normalizedAlgorithm.label) {
          normalizedAlgorithm.label = copyBuffer(normalizedAlgorithm.label);
        } else {
          normalizedAlgorithm.label = new Uint8Array();
        }
                const hashAlgorithm = key[_algorithm].hash.name;
        const cipherText = await core.opAsync("op_crypto_encrypt", {
          key: keyData,
          algorithm: "RSA-OAEP",
          hash: hashAlgorithm,
          label: normalizedAlgorithm.label,
        }, data);
                return cipherText.buffer;
      }
      case "AES-CBC": {
        normalizedAlgorithm.iv = copyBuffer(normalizedAlgorithm.iv);
                if (normalizedAlgorithm.iv.byteLength !== 16) {
          throw new DOMException(
            "Initialization vector must be 16 bytes",
            "OperationError",
          );
        }
                const cipherText = await core.opAsync("op_crypto_encrypt", {
          key: keyData,
          algorithm: "AES-CBC",
          length: key[_algorithm].length,
          iv: normalizedAlgorithm.iv,
        }, data);
                return cipherText.buffer;
      }
      case "AES-CTR": {
        normalizedAlgorithm.counter = copyBuffer(normalizedAlgorithm.counter);
                if (normalizedAlgorithm.counter.byteLength !== 16) {
          throw new DOMException(
            "Counter vector must be 16 bytes",
            "OperationError",
          );
        }
                if (
          normalizedAlgorithm.length == 0 || normalizedAlgorithm.length > 128
        ) {
          throw new DOMException(
            "Counter length must not be 0 or greater than 128",
            "OperationError",
          );
        }
                const cipherText = await core.opAsync("op_crypto_encrypt", {
          key: keyData,
          algorithm: "AES-CTR",
          keyLength: key[_algorithm].length,
          counter: normalizedAlgorithm.counter,
          ctrLength: normalizedAlgorithm.length,
        }, data);
                return cipherText.buffer;
      }
      case "AES-GCM": {
        normalizedAlgorithm.iv = copyBuffer(normalizedAlgorithm.iv);
                if (data.byteLength > (2 ** 39) - 256) {
          throw new DOMException(
            "Plaintext too large",
            "OperationError",
          );
        }
                        if (normalizedAlgorithm.iv.byteLength !== 12) {
          throw new DOMException(
            "Initialization vector length not supported",
            "NotSupportedError",
          );
        }
                if (normalizedAlgorithm.additionalData !== undefined) {
          if (normalizedAlgorithm.additionalData.byteLength > (2 ** 64) - 1) {
            throw new DOMException(
              "Additional data too large",
              "OperationError",
            );
          }
        }
                if (normalizedAlgorithm.tagLength == undefined) {
          normalizedAlgorithm.tagLength = 128;
        } else if (
          !ArrayPrototypeIncludes(
            [32, 64, 96, 104, 112, 120, 128],
            normalizedAlgorithm.tagLength,
          )
        ) {
          throw new DOMException(
            "Invalid tag length",
            "OperationError",
          );
        }
                if (normalizedAlgorithm.additionalData) {
          normalizedAlgorithm.additionalData = copyBuffer(
            normalizedAlgorithm.additionalData,
          );
        }
                const cipherText = await core.opAsync("op_crypto_encrypt", {
          key: keyData,
          algorithm: "AES-GCM",
          length: key[_algorithm].length,
          iv: normalizedAlgorithm.iv,
          additionalData: normalizedAlgorithm.additionalData,
          tagLength: normalizedAlgorithm.tagLength,
        }, data);
                return cipherText.buffer;
      }
      default:
        throw new DOMException("Not implemented", "NotSupportedError");
    }
  }
  webidl.configurePrototype(SubtleCrypto);
  const subtle = webidl.createBranded(SubtleCrypto);
  class Crypto {
    constructor() {
      webidl.illegalConstructor();
    }
    getRandomValues(arrayBufferView) {
      webidl.assertBranded(this, Crypto);
      const prefix = "Failed to execute 'getRandomValues' on 'Crypto'";
      webidl.requiredArguments(arguments.length, 1, { prefix });
      arrayBufferView = webidl.converters.ArrayBufferView(arrayBufferView, {
        prefix,
        context: "Argument 1",
      });
      if (
        !(
          arrayBufferView instanceof Int8Array ||
          arrayBufferView instanceof Uint8Array ||
          arrayBufferView instanceof Uint8ClampedArray ||
          arrayBufferView instanceof Int16Array ||
          arrayBufferView instanceof Uint16Array ||
          arrayBufferView instanceof Int32Array ||
          arrayBufferView instanceof Uint32Array ||
          arrayBufferView instanceof BigInt64Array ||
          arrayBufferView instanceof BigUint64Array
        )
      ) {
        throw new DOMException(
          "The provided ArrayBufferView is not an integer array type",
          "TypeMismatchError",
        );
      }
      const ui8 = new Uint8Array(
        arrayBufferView.buffer,
        arrayBufferView.byteOffset,
        arrayBufferView.byteLength,
      );
      core.opSync("op_crypto_get_random_values", ui8);
      return arrayBufferView;
    }
    randomUUID() {
      webidl.assertBranded(this, Crypto);
      return core.opSync("op_crypto_random_uuid");
    }
    get subtle() {
      webidl.assertBranded(this, Crypto);
      return subtle;
    }
    [SymbolFor("Deno.customInspect")](inspect) {
      return `${this.constructor.name} ${inspect({})}`;
    }
  }
  webidl.configurePrototype(Crypto);
  window.__bootstrap.crypto = {
    SubtleCrypto,
    crypto: webidl.createBranded(Crypto),
    Crypto,
    CryptoKey,
  };
})(this);