{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { hmac } from \"@noble/hashes/hmac.js\";\nimport { sha1 } from \"@noble/hashes/legacy.js\";\nimport { sha256, sha512 } from \"@noble/hashes/sha2.js\";\nimport { randomBytes } from \"@noble/hashes/utils.js\";\nimport { constantTimeEqual as constantTimeEqualUtil, normalizeHashAlgorithm } from \"@otplib/core\";\n\nimport type { CryptoPlugin, HashAlgorithm } from \"@otplib/core\";\n\n/**\n * Hash function lookup keyed by canonical algorithm name\n *\n * Deliberately has no fallback branch: unsupported values are rejected by\n * `normalizeHashAlgorithm` before they ever reach this map.\n *\n * The `satisfies` constraint forbids a key outside `HashAlgorithm`, so this\n * plugin cannot widen the allowlist, and requires every member of it, so a\n * newly supported algorithm fails to compile until it is dispatched here.\n */\nconst HASH_FNS = {\n  sha1,\n  sha256,\n  sha512,\n} as const satisfies Record<HashAlgorithm, unknown>;\n\n/**\n * Algorithms this plugin can compute\n *\n * Derived from the dispatch map rather than written out again, so the declared\n * set cannot disagree with what `hmac` actually handles. Frozen because\n * `readonly` is erased at compile time, so an unfrozen array exposed as\n * `plugin.algorithms` could be mutated in-process and make the capability\n * metadata unstable.\n */\nconst SUPPORTED_ALGORITHMS = Object.freeze(Object.keys(HASH_FNS) as HashAlgorithm[]);\n\n/**\n * Pure JavaScript implementation of CryptoPlugin\n *\n * This plugin uses @noble/hashes which provides:\n * - Pure JavaScript implementations of hash functions\n * - Zero dependencies and audited code\n * - Cross-platform compatibility (Node.js, browser, edge)\n * - Fallback for environments without native crypto APIs\n *\n * @example\n * ```ts\n * import { NobleCryptoPlugin } from '@otplib/plugin-crypto-noble';\n *\n * const crypto = new NobleCryptoPlugin();\n * const hmac = crypto.hmac('sha1', key, data);\n * const random = crypto.randomBytes(20);\n * ```\n */\nexport class NobleCryptoPlugin implements CryptoPlugin {\n  /**\n   * Plugin name for identification\n   */\n  readonly name = \"noble\";\n\n  /**\n   * Algorithms this plugin can compute\n   */\n  readonly algorithms = SUPPORTED_ALGORITHMS;\n\n  /**\n   * Compute HMAC using @noble/hashes\n   *\n   * Synchronous implementation using pure JS.\n   *\n   * The algorithm is matched ignoring case, with an optional `-` or `_` before\n   * the digest size, so `'SHA1'`, `'Sha1'` and `'SHA-1'` all resolve to\n   * `'sha1'`. Any other digest throws `AlgorithmUnsupportedError` rather than\n   * falling back to a default.\n   *\n   * @param algorithm - Hash algorithm to use\n   * @param key - Secret key\n   * @param data - Data to authenticate\n   * @returns HMAC digest\n   * @throws {AlgorithmUnsupportedError} If the algorithm is not supported\n   */\n  hmac(algorithm: HashAlgorithm, key: Uint8Array, data: Uint8Array): Uint8Array {\n    const alg = normalizeHashAlgorithm(algorithm, {\n      supported: this.algorithms,\n      plugin: this.name,\n    });\n    return hmac(HASH_FNS[alg], key, data);\n  }\n\n  /**\n   * Generate cryptographically secure random bytes\n   *\n   * Uses @noble/hashes' randomBytes which is backed by:\n   * - Node.js crypto.randomBytes in Node.js\n   * - crypto.getRandomValues in browsers\n   * - A PRNG as fallback\n   *\n   * @param length - Number of bytes to generate\n   * @returns Random bytes\n   */\n  randomBytes(length: number): Uint8Array {\n    return randomBytes(length);\n  }\n\n  /**\n   * Constant-time comparison to prevent timing side-channel attacks\n   *\n   * @noble/hashes doesn't provide a constant-time comparison,\n   * so we Use the core utility implementation.\n   *\n   * @param a - First value to compare\n   * @param b - Second value to compare\n   * @returns true if values are equal, false otherwise\n   */\n  constantTimeEqual(a: string | Uint8Array, b: string | Uint8Array): boolean {\n    return constantTimeEqualUtil(a, b);\n  }\n}\n\n/**\n * Default singleton instance for convenience\n *\n * @example\n * ```ts\n * import { crypto } from '@otplib/plugin-crypto-noble';\n *\n * const hmac = crypto.hmac('sha1', key, data);\n * ```\n */\nexport const crypto: CryptoPlugin = Object.freeze(new NobleCryptoPlugin());\n\nexport default NobleCryptoPlugin;\n"],"mappings":"yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,uBAAAE,EAAA,WAAAC,EAAA,YAAAC,IAAA,eAAAC,EAAAL,GAAA,IAAAM,EAAqB,iCACrBC,EAAqB,mCACrBC,EAA+B,iCAC/BC,EAA4B,kCAC5BC,EAAmF,wBAc7EC,EAAW,CACf,YACA,gBACA,eACF,EAWMC,EAAuB,OAAO,OAAO,OAAO,KAAKD,CAAQ,CAAoB,EAoBtET,EAAN,KAAgD,CAI5C,KAAO,QAKP,WAAaU,EAkBtB,KAAKC,EAA0BC,EAAiBC,EAA8B,CAC5E,IAAMC,KAAM,0BAAuBH,EAAW,CAC5C,UAAW,KAAK,WAChB,OAAQ,KAAK,IACf,CAAC,EACD,SAAO,QAAKF,EAASK,CAAG,EAAGF,EAAKC,CAAI,CACtC,CAaA,YAAYE,EAA4B,CACtC,SAAO,eAAYA,CAAM,CAC3B,CAYA,kBAAkBC,EAAwBC,EAAiC,CACzE,SAAO,EAAAC,mBAAsBF,EAAGC,CAAC,CACnC,CACF,EAYahB,EAAuB,OAAO,OAAO,IAAID,CAAmB,EAElEE,EAAQF","names":["index_exports","__export","NobleCryptoPlugin","crypto","index_default","__toCommonJS","import_hmac","import_legacy","import_sha2","import_utils","import_core","HASH_FNS","SUPPORTED_ALGORITHMS","algorithm","key","data","alg","length","a","b","constantTimeEqualUtil"]}