import { COSEKEYS, isCOSEAlg } from '../../cose.js'; import { isoBase64URL } from '../../index.js'; import { importJWKKey } from './importJWKKey.js'; import { getWebCrypto } from './getWebCrypto.js'; import { mapCoseAlgToWebCryptoKeyAlgName } from './mapCoseAlgToWebCryptoKeyAlgName.js'; import { PQCNotSupportedError } from '../../../errors/index.js'; /** AKP, a.k.a ML-DSA */ export async function verifyAKP(opts) { const { cosePublicKey, signature, data } = opts; const WebCrypto = await getWebCrypto(); const alg = cosePublicKey.get(COSEKEYS.alg); const pub = cosePublicKey.get(COSEKEYS.pub); if (!alg) { throw new Error('Public key was missing alg (AKP)'); } if (!isCOSEAlg(alg)) { throw new Error(`Public key had invalid alg ${alg} (AKP)`); } if (!pub) { throw new Error('Public key was missing pub (AKP)'); } const webCryptoAlg = mapCoseAlgToWebCryptoKeyAlgName(alg); // See https://wicg.github.io/webcrypto-modern-algos/#ml-dsa-operations-import-key -> "jwk" const keyData = { kty: 'AKP', alg: webCryptoAlg, pub: isoBase64URL.fromBuffer(pub), ext: false, }; /** * ML-DSA support is pretty cutting edge, so take some steps to help RP's understand this instead * of them getting a `NotSupportedError: Unrecognized algorithm name` and trying to interpret it. */ let key; try { key = await importJWKKey({ keyData, algorithm: webCryptoAlg }); } catch (err) { const _err = err; if (_err.name === 'NotSupportedError') { throw new PQCNotSupportedError(alg); } else { throw err; } } return WebCrypto.subtle.verify(webCryptoAlg, key, signature, data); }