Files

67 lines
2.6 KiB
JavaScript

/**
* NIP-QR algorithm policy (F-D3).
*
* The set of mandatory PQ algorithms is versioned and explicit. This module
* defines the policy object that verifyNIPQRContent() uses to decide which
* algorithms are mandatory, which are KEMs (no signature), and which are
* unknown (ignored — neither credit nor failure).
*
* Why a versioned, explicit policy:
* - The NIP's revocation path ("a user MAY publish a new key-link event
* omitting the broken scheme") only works if the mandatory set can change
* in a detectable way. A versioned policy makes that change explicit.
* - Unknown algorithms must NOT count as valid evidence (a malicious tag
* with a fake algorithm ID and a fake signature must not flip the
* verifier's result), but they also must NOT cause a policy failure
* (the NIP says clients verify whichever subset they support).
* - A future policy version can drop a broken scheme; verifiers that only
* know v1 reject v2 events fail-closed until upgraded.
*
* This is a pure data module with no imports, so it can be bundled and used
* both in the browser and in Node tests.
*/
/**
* Policy version 1 — the current mandatory set.
*
* - mandatorySignatureAlgorithms: every one MUST be present exactly once with
* a valid signature. Missing or duplicate => policy failure.
* - kemAlgorithms: every one MUST be present exactly once (pubkey only, no
* signature). Missing or duplicate => policy failure.
* - Algorithms not in either set are 'ignored': reported as valid:null, neither
* credit nor failure, and do not flip the legacy `valid` flag.
*/
export const POLICY_V1 = Object.freeze({
version: 1,
mandatorySignatureAlgorithms: Object.freeze(['ml-dsa-44', 'ml-dsa-65', 'slh-dsa-128s', 'falcon-512']),
kemAlgorithms: Object.freeze(['ml-kem-768'])
});
/**
* The default policy used by verifyNIPQRContent() when no policy is supplied.
*/
export const DEFAULT_POLICY = POLICY_V1;
/**
* Known algorithms (signature + KEM) for a given policy.
* @param {object} policy - a policy object like POLICY_V1
* @returns {Set<string>}
*/
export function knownAlgorithms(policy = DEFAULT_POLICY) {
return new Set([...policy.mandatorySignatureAlgorithms, ...policy.kemAlgorithms]);
}
/**
* Whether an algorithm id is a mandatory signature algorithm under the policy.
*/
export function isMandatorySignature(algorithmId, policy = DEFAULT_POLICY) {
return policy.mandatorySignatureAlgorithms.includes(algorithmId);
}
/**
* Whether an algorithm id is a KEM algorithm under the policy.
*/
export function isKem(algorithmId, policy = DEFAULT_POLICY) {
return policy.kemAlgorithms.includes(algorithmId);
}