2.1 KiB
2.1 KiB
sign
Purpose
COSE_Sign (RFC 9052 §4.1) — multi-signer COSE message in CBOR tag 98.
Use when a payload needs to be co-signed by multiple parties (e.g. multi-
party attestation, escrowed signing). Each signer carries its own protected
header (typically with its own alg) and produces an independent signature
over the canonical Sig_structure for context "Signature".
Features
encodeCoseSignbuilds the 4-tuple[bodyProtected, bodyUnprotected, payload, signatures]with deterministic encoding and per-signer[sigProtected, sigUnprotected, signature]triples.decodeCoseSignrecovers the typedCoseSignview, includingprotectedRawbyte strings on every level needed to recompute the five-elementSig_structure.verifyCoseSignAnywalks the signers in order against a 1:1 candidate- key array. Returns the first index whose signature verifies, or-1on no match. Caller decides whether one valid signer is enough or whether all signers must verify (loop the array).- Currently dispatches to ES256 + EdDSA via
@suaveplan/crypto-curve; unsupported algs returnfalse(signer is skipped) rather than throwing so the helper can scan a heterogeneous array without aborting.
Usage
import { encodeCoseSign, decodeCoseSign, verifyCoseSignAny } from "@suaveplan/cbor/cose";
const wire = encodeCoseSign({
payload,
signatures: [
{ protectedHeader: { alg: "ES256" }, signature: sig1 },
{ protectedHeader: { alg: "EdDSA" }, signature: sig2 },
],
});
const msg = decodeCoseSign(wire);
const matchIndex = verifyCoseSignAny(msg, [keyA, keyB]);
API
encodeCoseSign(input)/decodeCoseSign(bytes).verifyCoseSignAny(msg, keys, options?): number— returns matching index or-1. Length mismatch betweenkeysandmsg.signaturesthrowsUNEXPECTED_TYPE.COSE_SIGN_TAG = 98.
Notes
Sig_structure for multi-signer is 5-element:
[context, body_protected, sign_protected, external_aad, payload] — the
extra sign_protected discriminates the signer's own protected header from
the message-wide one. Both must be the SERIALISED byte strings, not the
inner maps.