@cardanowall/crypto-core 0.0.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -31
- package/dist/cbor.cjs +1 -1
- package/dist/cbor.cjs.map +1 -1
- package/dist/cbor.js +1 -1
- package/dist/cbor.js.map +1 -1
- package/dist/cose.cjs +11 -11
- package/dist/cose.cjs.map +1 -1
- package/dist/cose.d.cts +7 -7
- package/dist/cose.d.ts +7 -7
- package/dist/cose.js +9 -9
- package/dist/cose.js.map +1 -1
- package/dist/index.cjs +11 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +9 -9
- package/dist/index.js.map +1 -1
- package/dist/merkle.cjs +1 -1
- package/dist/merkle.cjs.map +1 -1
- package/dist/merkle.js +1 -1
- package/dist/merkle.js.map +1 -1
- package/dist/sealed-poe.cjs.map +1 -1
- package/dist/sealed-poe.js.map +1 -1
- package/package.json +6 -6
package/dist/cose.js
CHANGED
|
@@ -31,7 +31,7 @@ function decodeCanonicalCbor(bytes) {
|
|
|
31
31
|
...cdeDecodeOptions,
|
|
32
32
|
rejectStreaming: true,
|
|
33
33
|
rejectDuplicateKeys: true,
|
|
34
|
-
// A
|
|
34
|
+
// A Label 309 record carries integers, byte/text strings, arrays, maps and
|
|
35
35
|
// `null` — and nothing else. Without these rejections the major-type-7
|
|
36
36
|
// surface leaks into the decoder: a float16/32/64 that happens to hold an
|
|
37
37
|
// integral value (e.g. 1.0) silently decodes to the integer 1 and passes
|
|
@@ -141,7 +141,7 @@ function buildSigStructure(args) {
|
|
|
141
141
|
args.payload
|
|
142
142
|
]);
|
|
143
143
|
}
|
|
144
|
-
function
|
|
144
|
+
function buildLabel309SigStructure(args) {
|
|
145
145
|
const toSign = new Uint8Array(
|
|
146
146
|
CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length + args.recordBodyCbor.length
|
|
147
147
|
);
|
|
@@ -232,21 +232,21 @@ var CoseSign1BuildError = class extends Error {
|
|
|
232
232
|
this.code = code;
|
|
233
233
|
}
|
|
234
234
|
};
|
|
235
|
-
function
|
|
235
|
+
function coseSign1Label309Build(args) {
|
|
236
236
|
if (args.signerSecretKey === void 0 && args.signer === void 0) {
|
|
237
237
|
throw new CoseSign1BuildError(
|
|
238
238
|
"SIGNER_NOT_PROVIDED",
|
|
239
|
-
"
|
|
239
|
+
"coseSign1Label309Build requires either signerSecretKey or signer"
|
|
240
240
|
);
|
|
241
241
|
}
|
|
242
242
|
if (args.signerSecretKey !== void 0 && args.signer !== void 0) {
|
|
243
243
|
throw new CoseSign1BuildError(
|
|
244
244
|
"SIGNER_AND_SEED_BOTH_PROVIDED",
|
|
245
|
-
"
|
|
245
|
+
"coseSign1Label309Build accepts signerSecretKey XOR signer (not both)"
|
|
246
246
|
);
|
|
247
247
|
}
|
|
248
248
|
const protectedBytes = args.protectedHeader.size === 0 ? EMPTY_BYTES : encodeCanonicalCbor(args.protectedHeader);
|
|
249
|
-
const sigStructureBytes =
|
|
249
|
+
const sigStructureBytes = buildLabel309SigStructure({
|
|
250
250
|
bodyProtectedBytes: protectedBytes,
|
|
251
251
|
recordBodyCbor: args.recordBodyCbor
|
|
252
252
|
});
|
|
@@ -269,7 +269,7 @@ function coseSign1Cip309Build(args) {
|
|
|
269
269
|
signature
|
|
270
270
|
});
|
|
271
271
|
}
|
|
272
|
-
function
|
|
272
|
+
function coseSign1Label309Verify(args) {
|
|
273
273
|
let decoded;
|
|
274
274
|
try {
|
|
275
275
|
decoded = decodeCoseSign1(args.message);
|
|
@@ -336,7 +336,7 @@ function coseSign1Cip309Verify(args) {
|
|
|
336
336
|
payload: hashedPayload
|
|
337
337
|
});
|
|
338
338
|
} else {
|
|
339
|
-
sigStructureBytes =
|
|
339
|
+
sigStructureBytes = buildLabel309SigStructure({
|
|
340
340
|
bodyProtectedBytes: decoded.protectedBytes,
|
|
341
341
|
recordBodyCbor: args.detachedRecordBodyCbor
|
|
342
342
|
});
|
|
@@ -393,6 +393,6 @@ function parseCoseKeyEd25519(blob) {
|
|
|
393
393
|
return x;
|
|
394
394
|
}
|
|
395
395
|
|
|
396
|
-
export { CARDANO_POE_SIG_DOMAIN_PREFIX, CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES, CoseSign1BuildError, CoseVerifyError,
|
|
396
|
+
export { CARDANO_POE_SIG_DOMAIN_PREFIX, CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES, CoseSign1BuildError, CoseVerifyError, buildLabel309SigStructure, buildSigStructure, coseSign1Label309Build, coseSign1Label309Verify, decodeCoseSign1, encodeCoseSign1, parseCoseKeyEd25519 };
|
|
397
397
|
//# sourceMappingURL=cose.js.map
|
|
398
398
|
//# sourceMappingURL=cose.js.map
|
package/dist/cose.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cbor/errors.ts","../src/cbor/canonical.ts","../src/hash/blake2b-256.ts","../src/sig/ed25519.ts","../src/util/compare-ct.ts","../src/cose/errors.ts","../src/cose/sign1.ts","../src/cose/cose-key.ts"],"names":[],"mappings":"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","file":"cose.js","sourcesContent":["// Every canonical-CBOR decode violation collapses to the single public CIP-309\n// taxonomy code MALFORMED_CBOR: indefinite-length (streaming) items, duplicate\n// keys, unsorted keys, non-minimal integer encodings, and invalid UTF-8 in text\n// strings. The taxonomy intentionally has one code for all of these; the\n// specific cause survives in the human-readable error message, not as a\n// separate code.\nexport type CanonicalCborErrorCode = 'MALFORMED_CBOR';\n\nexport class CanonicalCborError extends Error {\n readonly code: CanonicalCborErrorCode;\n\n constructor(code: CanonicalCborErrorCode, message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = 'CanonicalCborError';\n this.code = code;\n }\n}\n","import { cdeDecodeOptions, decode, encode } from 'cbor2';\nimport { sortCoreDeterministic } from 'cbor2/sorts';\n\nimport { CanonicalCborError } from './errors';\n\nexport type CanonicalCborValue =\n | null\n | boolean\n | number\n | bigint\n | string\n | Uint8Array\n | readonly CanonicalCborValue[]\n | { readonly [key: string]: CanonicalCborValue }\n | ReadonlyMap<string | number, CanonicalCborValue>;\n\nexport function encodeCanonicalCbor(value: CanonicalCborValue): Uint8Array {\n return encode(value, {\n cde: true,\n collapseBigInts: true,\n rejectDuplicateKeys: true,\n sortKeys: sortCoreDeterministic,\n });\n}\n\nexport function decodeCanonicalCbor(bytes: Uint8Array): unknown {\n try {\n return decode(bytes, {\n ...cdeDecodeOptions,\n rejectStreaming: true,\n rejectDuplicateKeys: true,\n // A CIP-309 record carries integers, byte/text strings, arrays, maps and\n // `null` — and nothing else. Without these rejections the major-type-7\n // surface leaks into the decoder: a float16/32/64 that happens to hold an\n // integral value (e.g. 1.0) silently decodes to the integer 1 and passes\n // a `z.literal(1)` / Number.isInteger schema check, so two byte strings\n // that are NOT byte-identical canonicalise to the same record. That\n // breaks the cross-implementation parity invariant (the Python twin\n // already rejects non-integer `v` / `enc.scheme` outright). Reject the\n // whole non-record surface — floats, negative zero, undefined, and\n // non-{true,false,null} simple values — so any such input surfaces as\n // MALFORMED_CBOR via mapDecodeError rather than decoding to a look-alike.\n rejectFloats: true,\n rejectNegativeZero: true,\n rejectUndefined: true,\n rejectSimple: true,\n });\n } catch (cause) {\n throw mapDecodeError(cause);\n }\n}\n\nfunction mapDecodeError(cause: unknown): CanonicalCborError {\n const message = cause instanceof Error ? cause.message : String(cause);\n const lower = message.toLowerCase();\n // Every canonical-decode violation collapses to the single public taxonomy\n // code MALFORMED_CBOR: indefinite-length (streaming) items, duplicate keys,\n // non-canonical (unsorted) key ordering, non-minimal integer encodings, and\n // invalid UTF-8 in text strings. cbor2 raises the SAME \"Duplicate or out of\n // order key\" message for both true duplicates AND distinct-but-unsorted keys,\n // so the two are indistinguishable by message — and per the CIP-309 taxonomy\n // both belong under MALFORMED_CBOR anyway. The specific cause survives in the\n // human-readable message below; for indefinite-length we state it explicitly\n // so the diagnostic is not lost when the code is collapsed.\n const isIndefinite = lower.includes('streaming') || lower.includes('indefinite');\n const detail = isIndefinite\n ? `indefinite-length items are not permitted in canonical CBOR: ${message}`\n : message;\n return new CanonicalCborError('MALFORMED_CBOR', `cbor decode failed: ${detail}`, { cause });\n}\n","import { blake2b } from '@noble/hashes/blake2.js';\n\nexport function blake2b256(input: Uint8Array): Uint8Array {\n return blake2b(input, { dkLen: 32 });\n}\n\n// CIP-19 stake-address derivation, used for the wallet path-2 signer binding,\n// requires the 28-byte BLAKE2b digest of the signer's Ed25519 public key.\n// The Cardano ledger encodes stake addresses as\n// `network_header_byte || Blake2b-224(stake_vk)`\n// per CIP-19, so this output length is fixed by spec.\nexport function blake2b224(input: Uint8Array): Uint8Array {\n return blake2b(input, { dkLen: 28 });\n}\n","import * as ed from '@noble/ed25519';\nimport { sha512 } from '@noble/hashes/sha2.js';\n\ned.hashes.sha512 = sha512;\n\n// Ed25519 group order L (= 2^252 + 27742317777372353535851937790883648493).\nconst L = ed.Point.CURVE().n;\n\nexport interface SignEd25519Opts {\n readonly seed: Uint8Array;\n readonly message: Uint8Array;\n}\n\nexport interface VerifyEd25519Opts {\n readonly publicKey: Uint8Array;\n readonly message: Uint8Array;\n readonly signature: Uint8Array;\n}\n\nexport interface GetPublicKeyEd25519Opts {\n readonly seed: Uint8Array;\n}\n\nexport function signEd25519(opts: SignEd25519Opts): Uint8Array {\n return ed.sign(opts.message, opts.seed);\n}\n\n// Little-endian 32-byte scalar → bigint.\nfunction leBytesToBigInt(bytes: Uint8Array): bigint {\n let value = 0n;\n for (let i = bytes.length - 1; i >= 0; i--) {\n value = (value << 8n) | BigInt(bytes[i]!);\n }\n return value;\n}\n\n// Strict (non-cofactored) Ed25519 verification per RFC 8032 §5.1.7, matching\n// libsodium/PyNaCl `crypto_sign_verify_detached` and ed25519-dalek\n// `verify_strict`. The cofactor-less check rejects every small-order /\n// torsion-component edge case in the C2SP/CCTV corpus, which noble's\n// `{ zip215: false }` mode does NOT (it remains cofactored: it checks\n// `[8]([S]B - [k]A - R) == 0`, accepting torsion components).\n//\n// The verification equation is the unscaled `[S]B == R + [k]A`, rewritten as\n// `[S]B - [k]A - R == identity`. We reject S >= L (non-canonical scalar) and\n// any small-order A or R up front, so a torsion component can never be smuggled\n// through the cofactor multiplication the cofactored variant performs.\nexport function verifyEd25519(opts: VerifyEd25519Opts): boolean {\n const { signature, message, publicKey } = opts;\n if (signature.length !== 64 || publicKey.length !== 32) return false;\n\n // S = LE(sig[32..64]); reject if not a canonical scalar (S >= L).\n const S = leBytesToBigInt(signature.subarray(32, 64));\n if (S >= L) return false;\n\n // Decode A (public key) and R (sig[0..32]) with the canonical (non-zip215)\n // point encoding; a non-canonical encoding throws and rejects.\n let A: ed.Point;\n let R: ed.Point;\n try {\n A = ed.Point.fromBytes(publicKey);\n R = ed.Point.fromBytes(signature.subarray(0, 32));\n } catch {\n return false;\n }\n\n // Reject small-order (cofactor-torsion) A or R: this is exactly the strictness\n // that distinguishes verify_strict from the cofactored check.\n if (A.isSmallOrder() || R.isSmallOrder()) return false;\n\n // k = SHA-512(R || A || M) reduced mod L.\n const k =\n leBytesToBigInt(ed.hash(concatBytes(signature.subarray(0, 32), publicKey, message))) % L;\n\n // Accept iff [S]B - [k]A - R == identity. `multiplyUnsafe` returns the\n // identity for a 0 scalar, but guard explicitly to avoid relying on that.\n const sB = S === 0n ? ed.Point.ZERO : ed.Point.BASE.multiplyUnsafe(S);\n const kA = k === 0n ? ed.Point.ZERO : A.multiplyUnsafe(k);\n return sB.subtract(kA).subtract(R).is0();\n}\n\nfunction concatBytes(...parts: Uint8Array[]): Uint8Array {\n let total = 0;\n for (const p of parts) total += p.length;\n const out = new Uint8Array(total);\n let offset = 0;\n for (const p of parts) {\n out.set(p, offset);\n offset += p.length;\n }\n return out;\n}\n\nexport function getPublicKeyEd25519(opts: GetPublicKeyEd25519Opts): Uint8Array {\n return ed.getPublicKey(opts.seed);\n}\n","// Isomorphic constant-time byte-equality. crypto-core is browser-safe by\n// design, so we cannot import `node:crypto.timingSafeEqual` — webpack rejects\n// the `node:` scheme in the browser bundle. A pure-JS XOR loop is constant-time\n// for equal-length inputs; length mismatch is a deliberate early-return (the\n// API surface itself leaks length, same as node's timingSafeEqual which throws).\nexport function compareCt(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n // Lengths are equal and `i` stays in-bounds, so both indexes are always\n // defined — no nullish guard is needed (and one would read as a guard for\n // an impossible case).\n for (let i = 0; i < a.length; i++) diff |= (a[i] as number) ^ (b[i] as number);\n return diff === 0;\n}\n","export type CoseVerifyErrorCode =\n | 'MALFORMED_SIG_COSE'\n | 'MALFORMED_SIG_COSE_SIGN1'\n | 'UNSUPPORTED_SIG_ALG'\n | 'KID_UNRESOLVED'\n | 'SIGNATURE_INVALID';\n\nexport class CoseVerifyError extends Error {\n readonly code: CoseVerifyErrorCode;\n\n constructor(code: CoseVerifyErrorCode, message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = 'CoseVerifyError';\n this.code = code;\n }\n}\n\nexport type CoseVerifyResult =\n | { ok: true; signerKey: Uint8Array; alg: number }\n | { ok: false; error: { code: CoseVerifyErrorCode; message: string } };\n","import {\n decodeCanonicalCbor,\n encodeCanonicalCbor,\n type CanonicalCborValue,\n} from '../cbor/canonical';\nimport { CanonicalCborError } from '../cbor/errors';\nimport { blake2b224 } from '../hash/blake2b-256';\nimport { signEd25519, verifyEd25519 } from '../sig/ed25519';\nimport { compareCt } from '../util/compare-ct';\n\nimport { CoseVerifyError, type CoseVerifyResult } from './errors';\n\nexport type CoseHeader = Map<number | string, unknown>;\n\n// CIP-309 v1 domain separator embedded as a prefix on `Sig_structure[3]`\n// (`to_sign`). The separator is\n// NOT placed in `Sig_structure[2]` (`external_aad`) because CIP-30 `signData`\n// — the only realistic wallet-signing path on Cardano — explicitly forbids a\n// non-empty `external_aad`. Pinning the prefix into the payload preserves the\n// anti-replay property while keeping wallet-produced signatures byte-identical\n// to verifier-side recomputation.\nexport const CARDANO_POE_SIG_DOMAIN_PREFIX = 'cardano-poe-record-sig-v1' as const;\n// Composer path-2 wallet flow consumes the prefix bytes directly\n// to assemble `toSign = prefix || canonical_cbor(record_body)` BEFORE calling\n// `walletSignData` (the wallet's `signData()` receives this concatenation as\n// its `payload` argument verbatim per CIP-30). The bytes constant is exported\n// so a composer can build the input without re-encoding the prefix at every\n// call site.\nexport const CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES = new TextEncoder().encode(\n CARDANO_POE_SIG_DOMAIN_PREFIX,\n);\n\n// Fail-fast: the prefix length is byte-pinned at 25 UTF-8 bytes. A different\n// runtime encoding would silently break round-tripping\n// against the reference vectors.\nif (CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length !== 25) {\n throw new Error(\n `cardano-poe-record-sig-v1 prefix must encode to exactly 25 UTF-8 bytes, got ${CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length}`,\n );\n}\n\nconst EMPTY_BYTES = new Uint8Array(0);\n\nexport interface CoseSign1Decoded {\n readonly protectedHeader: CoseHeader;\n // preserved for Sig_structure reconstruction — never re-encode the decoded header map (RFC 9052 §4.4)\n readonly protectedBytes: Uint8Array;\n readonly unprotectedHeader: CoseHeader;\n readonly payload: Uint8Array | null;\n readonly signature: Uint8Array;\n}\n\nexport interface BuildSigStructureArgs {\n readonly context: 'Signature1';\n readonly bodyProtectedBytes: Uint8Array;\n readonly externalAad: Uint8Array;\n readonly payload: Uint8Array;\n}\n\n// Raw RFC 9052 §4.4 Sig_structure builder. General-purpose: callers control\n// `external_aad` and `payload` exactly. For CIP-309 record signing use\n// `buildCip309SigStructure` instead — it enforces the CIP-309 record-signature invariants.\nexport function buildSigStructure(args: BuildSigStructureArgs): Uint8Array {\n return encodeCanonicalCbor([\n args.context,\n args.bodyProtectedBytes,\n args.externalAad,\n args.payload,\n ] as readonly CanonicalCborValue[]);\n}\n\nexport interface BuildCip309SigStructureArgs {\n readonly bodyProtectedBytes: Uint8Array;\n // Canonical CBOR of the record body with `sigs` removed.\n readonly recordBodyCbor: Uint8Array;\n}\n\n// CIP-309 v1 specialisation of `Sig_structure` (RFC 9052 §4.4 base structure):\n// to_sign = utf8(\"cardano-poe-record-sig-v1\") || canonical_cbor(record_body_minus_sigs)\n// Sig_structure = [ \"Signature1\", body_protected, h'' (empty), to_sign ]\n// Always forces `external_aad = h''` (empty bstr) — the CIP-30 wallet path\n// cannot carry a non-empty `external_aad`, so the domain separator lives in\n// `Sig_structure[3]` rather than `Sig_structure[2]`.\nexport function buildCip309SigStructure(args: BuildCip309SigStructureArgs): Uint8Array {\n const toSign = new Uint8Array(\n CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length + args.recordBodyCbor.length,\n );\n toSign.set(CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES, 0);\n toSign.set(args.recordBodyCbor, CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length);\n return buildSigStructure({\n context: 'Signature1',\n bodyProtectedBytes: args.bodyProtectedBytes,\n externalAad: EMPTY_BYTES,\n payload: toSign,\n });\n}\n\nexport interface EncodeCoseSign1Args {\n readonly protectedHeader: CoseHeader;\n readonly unprotectedHeader: CoseHeader;\n readonly payload: Uint8Array | null;\n readonly signature: Uint8Array;\n}\n\nexport function encodeCoseSign1(args: EncodeCoseSign1Args): Uint8Array {\n const protectedBytes =\n args.protectedHeader.size === 0\n ? EMPTY_BYTES\n : encodeCanonicalCbor(args.protectedHeader as CanonicalCborValue);\n return encodeCanonicalCbor([\n protectedBytes,\n args.unprotectedHeader as CanonicalCborValue,\n args.payload,\n args.signature,\n ] as readonly CanonicalCborValue[]);\n}\n\n// cbor2's decoder returns Map for integer-keyed maps but plain Object for empty\n// or string-keyed maps; normalise both representations to Map.\nfunction asCoseHeader(value: unknown): CoseHeader | null {\n if (value instanceof Map) return value as CoseHeader;\n if (value !== null && typeof value === 'object' && (value as object).constructor === Object) {\n return new Map(Object.entries(value as Record<string, unknown>));\n }\n return null;\n}\n\nexport function decodeCoseSign1(bytes: Uint8Array): CoseSign1Decoded {\n let arr: unknown;\n try {\n arr = decodeCanonicalCbor(bytes);\n } catch (cause) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'cose decode failed', { cause });\n }\n if (!Array.isArray(arr) || arr.length !== 4) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'expected 4-element array');\n }\n const [protectedBytesRaw, unprotectedRaw, payloadRaw, signatureRaw] = arr;\n if (!(protectedBytesRaw instanceof Uint8Array)) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'protected_bytes must be bytes');\n }\n const unprotectedHeader = asCoseHeader(unprotectedRaw);\n if (unprotectedHeader === null) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'unprotected header must be map');\n }\n if (payloadRaw !== null && !(payloadRaw instanceof Uint8Array)) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'payload must be bytes or null');\n }\n if (!(signatureRaw instanceof Uint8Array) || signatureRaw.length !== 64) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'signature must be 64 bytes');\n }\n let protectedHeader: CoseHeader;\n if (protectedBytesRaw.length === 0) {\n protectedHeader = new Map();\n } else {\n let decodedProtected: unknown;\n try {\n decodedProtected = decodeCanonicalCbor(protectedBytesRaw);\n } catch (cause) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'protected header decode failed', { cause });\n }\n const ph = asCoseHeader(decodedProtected);\n if (ph === null) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'protected header must decode to map');\n }\n // Empty protected header MUST encode as the single byte 0x40 (zero-length bstr),\n // not 0x41 0xA0 (a 1-byte bstr containing an empty CBOR map). RFC 9052 §3 +\n // CIP-309 canonical-CBOR mandate.\n if (ph.size === 0) {\n throw new CoseVerifyError(\n 'MALFORMED_SIG_COSE',\n 'empty protected header must encode as 0x40 (zero-length bstr), not as an empty map',\n );\n }\n protectedHeader = ph;\n }\n return {\n protectedHeader,\n protectedBytes: protectedBytesRaw,\n unprotectedHeader,\n payload: payloadRaw,\n signature: signatureRaw,\n };\n}\n\nexport type CoseSign1BuildErrorCode = 'SIGNER_NOT_PROVIDED' | 'SIGNER_AND_SEED_BOTH_PROVIDED';\n\nexport class CoseSign1BuildError extends Error {\n readonly code: CoseSign1BuildErrorCode;\n\n constructor(code: CoseSign1BuildErrorCode, message: string) {\n super(message);\n this.name = 'CoseSign1BuildError';\n this.code = code;\n }\n}\n\nexport interface CoseSign1Cip309BuildArgs {\n readonly protectedHeader: CoseHeader;\n readonly unprotectedHeader: CoseHeader;\n // Canonical CBOR of the record body with `sigs` removed. The\n // builder prepends the 25-byte UTF-8 domain prefix `cardano-poe-record-sig-v1`\n // internally — callers MUST NOT pre-concatenate it.\n readonly recordBodyCbor: Uint8Array;\n // EITHER the raw 32-byte Ed25519 seed (used by KAT tests, Python parity, and\n // the off-host signing helper) OR an injected signer closure that signs the\n // assembled Sig_structure bytes (composer-side use — keeps the private key\n // inside the unlock-store closure so it never escapes scope).\n // Exactly one of the two MUST be provided; mutual exclusion enforced at\n // runtime via CoseSign1BuildError.\n readonly signerSecretKey?: Uint8Array;\n readonly signer?: (sigStructureBytes: Uint8Array) => Uint8Array;\n}\n\n// CIP-309 v1 record-signature builder:\n// 1. compute `to_sign = utf8(\"cardano-poe-record-sig-v1\") || recordBodyCbor`\n// 2. Sig_structure = [ \"Signature1\", bodyProtected, h'', to_sign ]\n// 3. Ed25519-sign Sig_structure (via seed OR injected closure)\n// 4. emit COSE_Sign1 with payload = CBOR null (detached signature, mandatory)\nexport function coseSign1Cip309Build(args: CoseSign1Cip309BuildArgs): Uint8Array {\n if (args.signerSecretKey === undefined && args.signer === undefined) {\n throw new CoseSign1BuildError(\n 'SIGNER_NOT_PROVIDED',\n 'coseSign1Cip309Build requires either signerSecretKey or signer',\n );\n }\n if (args.signerSecretKey !== undefined && args.signer !== undefined) {\n throw new CoseSign1BuildError(\n 'SIGNER_AND_SEED_BOTH_PROVIDED',\n 'coseSign1Cip309Build accepts signerSecretKey XOR signer (not both)',\n );\n }\n const protectedBytes =\n args.protectedHeader.size === 0\n ? EMPTY_BYTES\n : encodeCanonicalCbor(args.protectedHeader as CanonicalCborValue);\n const sigStructureBytes = buildCip309SigStructure({\n bodyProtectedBytes: protectedBytes,\n recordBodyCbor: args.recordBodyCbor,\n });\n let signature: Uint8Array;\n if (args.signer !== undefined) {\n signature = args.signer(sigStructureBytes);\n if (!(signature instanceof Uint8Array) || signature.length !== 64) {\n throw new CoseSign1BuildError(\n 'SIGNER_NOT_PROVIDED',\n `injected signer must return a 64-byte Uint8Array; got ${signature instanceof Uint8Array ? `${signature.length}-byte Uint8Array` : typeof signature}`,\n );\n }\n } else {\n signature = signEd25519({ seed: args.signerSecretKey!, message: sigStructureBytes });\n }\n return encodeCoseSign1({\n protectedHeader: args.protectedHeader,\n unprotectedHeader: args.unprotectedHeader,\n payload: null,\n signature,\n });\n}\n\nexport interface CoseSign1Cip309VerifyArgs {\n readonly message: Uint8Array;\n // Canonical CBOR of the record body with `sigs` removed (verifier-recomputed;\n // the 25-byte UTF-8 prefix is prepended internally — callers\n // MUST NOT pre-concatenate it).\n readonly detachedRecordBodyCbor: Uint8Array;\n // Optional out-of-band signer key (path-2 wallet path resolves the key from\n // `sigs[i].cose_key`). Path-1 records carry the 32-byte raw Ed25519 pubkey\n // in the protected header at label 4 (`kid`) and need no out-of-band hint.\n readonly expectedSignerKey?: Uint8Array;\n}\n\n// CIP-309 v1 record-signature verifier:\n// - Decode COSE_Sign1\n// - Reject COSE_Sign1[2] != CBOR null (attached payload — including h'') as\n// MALFORMED_SIG_COSE_SIGN1\n// - Recompute to_sign = utf8(\"cardano-poe-record-sig-v1\") || detachedRecordBodyCbor\n// - Sig_structure = [ \"Signature1\", protectedBytes, h'', to_sign ]\n// - Strict Ed25519 verify (RFC 8032 §5.1.7 — `zip215: false` per ed25519.ts)\n//\n// The verifier does NOT accept an `externalAad` argument: CIP-309 v1 pins\n// `external_aad = h''` and any deviation would either silently weaken the\n// domain separator or quietly accept malformed records. If a future CIP\n// revision re-enables external_aad, this helper takes a v-bump.\nexport function coseSign1Cip309Verify(args: CoseSign1Cip309VerifyArgs): CoseVerifyResult {\n let decoded: CoseSign1Decoded;\n try {\n decoded = decodeCoseSign1(args.message);\n } catch (e) {\n if (e instanceof CoseVerifyError) {\n return { ok: false, error: { code: e.code, message: 'errors.cose.malformed' } };\n }\n if (e instanceof CanonicalCborError) {\n return {\n ok: false,\n error: { code: 'MALFORMED_SIG_COSE', message: 'errors.cose.malformed_cbor' },\n };\n }\n throw e;\n }\n // CIP-309 v1 mandate: COSE_Sign1[2] (payload field) MUST be CBOR `null` (0xF6).\n // Any non-null payload — including a zero-length byte string `h''` — MUST\n // be rejected as MALFORMED_SIG_COSE_SIGN1.\n if (decoded.payload !== null) {\n return {\n ok: false,\n error: {\n code: 'MALFORMED_SIG_COSE_SIGN1',\n message: 'errors.cose.attached_payload_forbidden',\n },\n };\n }\n const alg = decoded.protectedHeader.get(1);\n if (typeof alg !== 'number' || alg !== -8) {\n return {\n ok: false,\n error: { code: 'UNSUPPORTED_SIG_ALG', message: 'errors.cose.unsupported_alg' },\n };\n }\n const kidRaw = decoded.protectedHeader.get(4);\n let signerKey: Uint8Array | undefined;\n if (kidRaw instanceof Uint8Array && kidRaw.length === 32) {\n signerKey = kidRaw;\n } else if (args.expectedSignerKey instanceof Uint8Array && args.expectedSignerKey.length === 32) {\n signerKey = args.expectedSignerKey;\n }\n if (signerKey === undefined) {\n return {\n ok: false,\n error: { code: 'KID_UNRESOLVED', message: 'errors.cose.kid_unresolved' },\n };\n }\n // When both a protected-header kid AND an expectedSignerKey are provided,\n // require they agree (constant-time). A protected kid that disagrees with\n // the caller's out-of-band binding is a misuse, not a transient mismatch.\n if (\n kidRaw instanceof Uint8Array &&\n kidRaw.length === 32 &&\n args.expectedSignerKey instanceof Uint8Array &&\n args.expectedSignerKey.length === 32 &&\n !compareCt(kidRaw, args.expectedSignerKey)\n ) {\n return {\n ok: false,\n error: { code: 'KID_UNRESOLVED', message: 'errors.cose.kid_mismatch' },\n };\n }\n // CIP-8 `hashed = true` mode (the wallet-signed path-2 variant). The unprotected\n // header carries the literal text key `\"hashed\"` with boolean value `true`\n // (text-keyed CBOR maps decode to `Map<string, unknown>` via cbor2). When\n // set, both producer and verifier build `Sig_structure[3] = Blake2b-224(to_sign)`\n // (28-byte digest of the FULL `to_sign` payload including the 25-byte\n // domain prefix). When absent or false, the standard non-hashed path\n // applies unchanged.\n const hashedFlag = decoded.unprotectedHeader.get('hashed');\n let sigStructureBytes: Uint8Array;\n if (hashedFlag === true) {\n const toSign = new Uint8Array(\n CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length + args.detachedRecordBodyCbor.length,\n );\n toSign.set(CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES, 0);\n toSign.set(args.detachedRecordBodyCbor, CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length);\n const hashedPayload = blake2b224(toSign);\n sigStructureBytes = buildSigStructure({\n context: 'Signature1',\n bodyProtectedBytes: decoded.protectedBytes,\n externalAad: EMPTY_BYTES,\n payload: hashedPayload,\n });\n } else {\n sigStructureBytes = buildCip309SigStructure({\n bodyProtectedBytes: decoded.protectedBytes,\n recordBodyCbor: args.detachedRecordBodyCbor,\n });\n }\n const valid = verifyEd25519({\n publicKey: signerKey,\n message: sigStructureBytes,\n signature: decoded.signature,\n });\n if (!valid) {\n return {\n ok: false,\n error: { code: 'SIGNATURE_INVALID', message: 'errors.cose.signature_invalid' },\n };\n }\n return { ok: true, signerKey, alg };\n}\n","// CIP-30 / RFC 9052 §7 COSE_Key extraction for the Ed25519 sig path.\n//\n// CIP-30 wallets that don't put a 32-byte raw Ed25519 pubkey in the COSE_Sign1\n// protected header instead deliver the signer key as a separate `cbor<COSE_Key>`\n// blob, surfaced in the CIP-309 record under the top-level `signer_keys` field.\n// This helper decodes one such blob and returns the underlying 32-byte Ed25519\n// pubkey, or `null` when the blob is malformed, uses an unexpected key type /\n// curve, or has the wrong `x` length.\n//\n// The expected COSE_Key shape (RFC 9053 §7.2 + RFC 8152 §13):\n// {\n// 1 (kty): 1 // OKP\n// 3 (alg): -8 // EdDSA — OPTIONAL but if present MUST be -8\n// -1 (crv): 6 // Ed25519\n// -2 (x): <32 byte raw public key>\n// }\n\nimport { decodeCanonicalCbor } from '../cbor/canonical';\n\nconst COSE_KEY_LABEL_KTY = 1;\nconst COSE_KEY_LABEL_ALG = 3;\nconst COSE_KEY_LABEL_CRV = -1;\nconst COSE_KEY_LABEL_X = -2;\n\nconst KTY_OKP = 1;\nconst ALG_EDDSA = -8;\nconst CRV_ED25519 = 6;\n\nconst ED25519_PUBLIC_KEY_LENGTH = 32;\n\nfunction asMap(value: unknown): Map<unknown, unknown> | null {\n if (value instanceof Map) return value as Map<unknown, unknown>;\n if (value !== null && typeof value === 'object' && (value as object).constructor === Object) {\n return new Map(Object.entries(value as Record<string, unknown>));\n }\n return null;\n}\n\nexport function parseCoseKeyEd25519(blob: Uint8Array): Uint8Array | null {\n let decoded: unknown;\n try {\n decoded = decodeCanonicalCbor(blob);\n } catch {\n return null;\n }\n const map = asMap(decoded);\n if (map === null) return null;\n\n const kty = map.get(COSE_KEY_LABEL_KTY);\n if (typeof kty !== 'number' || kty !== KTY_OKP) return null;\n\n const crv = map.get(COSE_KEY_LABEL_CRV);\n if (typeof crv !== 'number' || crv !== CRV_ED25519) return null;\n\n if (map.has(COSE_KEY_LABEL_ALG)) {\n const alg = map.get(COSE_KEY_LABEL_ALG);\n if (typeof alg !== 'number' || alg !== ALG_EDDSA) return null;\n }\n\n const x = map.get(COSE_KEY_LABEL_X);\n if (!(x instanceof Uint8Array) || x.length !== ED25519_PUBLIC_KEY_LENGTH) return null;\n\n return x;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/cbor/errors.ts","../src/cbor/canonical.ts","../src/hash/blake2b-256.ts","../src/sig/ed25519.ts","../src/util/compare-ct.ts","../src/cose/errors.ts","../src/cose/sign1.ts","../src/cose/cose-key.ts"],"names":[],"mappings":"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","file":"cose.js","sourcesContent":["// Every canonical-CBOR decode violation collapses to the single public Label 309\n// taxonomy code MALFORMED_CBOR: indefinite-length (streaming) items, duplicate\n// keys, unsorted keys, non-minimal integer encodings, and invalid UTF-8 in text\n// strings. The taxonomy intentionally has one code for all of these; the\n// specific cause survives in the human-readable error message, not as a\n// separate code.\nexport type CanonicalCborErrorCode = 'MALFORMED_CBOR';\n\nexport class CanonicalCborError extends Error {\n readonly code: CanonicalCborErrorCode;\n\n constructor(code: CanonicalCborErrorCode, message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = 'CanonicalCborError';\n this.code = code;\n }\n}\n","import { cdeDecodeOptions, decode, encode } from 'cbor2';\nimport { sortCoreDeterministic } from 'cbor2/sorts';\n\nimport { CanonicalCborError } from './errors';\n\nexport type CanonicalCborValue =\n | null\n | boolean\n | number\n | bigint\n | string\n | Uint8Array\n | readonly CanonicalCborValue[]\n | { readonly [key: string]: CanonicalCborValue }\n | ReadonlyMap<string | number, CanonicalCborValue>;\n\nexport function encodeCanonicalCbor(value: CanonicalCborValue): Uint8Array {\n return encode(value, {\n cde: true,\n collapseBigInts: true,\n rejectDuplicateKeys: true,\n sortKeys: sortCoreDeterministic,\n });\n}\n\nexport function decodeCanonicalCbor(bytes: Uint8Array): unknown {\n try {\n return decode(bytes, {\n ...cdeDecodeOptions,\n rejectStreaming: true,\n rejectDuplicateKeys: true,\n // A Label 309 record carries integers, byte/text strings, arrays, maps and\n // `null` — and nothing else. Without these rejections the major-type-7\n // surface leaks into the decoder: a float16/32/64 that happens to hold an\n // integral value (e.g. 1.0) silently decodes to the integer 1 and passes\n // a `z.literal(1)` / Number.isInteger schema check, so two byte strings\n // that are NOT byte-identical canonicalise to the same record. That\n // breaks the cross-implementation parity invariant (the Python twin\n // already rejects non-integer `v` / `enc.scheme` outright). Reject the\n // whole non-record surface — floats, negative zero, undefined, and\n // non-{true,false,null} simple values — so any such input surfaces as\n // MALFORMED_CBOR via mapDecodeError rather than decoding to a look-alike.\n rejectFloats: true,\n rejectNegativeZero: true,\n rejectUndefined: true,\n rejectSimple: true,\n });\n } catch (cause) {\n throw mapDecodeError(cause);\n }\n}\n\nfunction mapDecodeError(cause: unknown): CanonicalCborError {\n const message = cause instanceof Error ? cause.message : String(cause);\n const lower = message.toLowerCase();\n // Every canonical-decode violation collapses to the single public taxonomy\n // code MALFORMED_CBOR: indefinite-length (streaming) items, duplicate keys,\n // non-canonical (unsorted) key ordering, non-minimal integer encodings, and\n // invalid UTF-8 in text strings. cbor2 raises the SAME \"Duplicate or out of\n // order key\" message for both true duplicates AND distinct-but-unsorted keys,\n // so the two are indistinguishable by message — and per the Label 309 taxonomy\n // both belong under MALFORMED_CBOR anyway. The specific cause survives in the\n // human-readable message below; for indefinite-length we state it explicitly\n // so the diagnostic is not lost when the code is collapsed.\n const isIndefinite = lower.includes('streaming') || lower.includes('indefinite');\n const detail = isIndefinite\n ? `indefinite-length items are not permitted in canonical CBOR: ${message}`\n : message;\n return new CanonicalCborError('MALFORMED_CBOR', `cbor decode failed: ${detail}`, { cause });\n}\n","import { blake2b } from '@noble/hashes/blake2.js';\n\nexport function blake2b256(input: Uint8Array): Uint8Array {\n return blake2b(input, { dkLen: 32 });\n}\n\n// CIP-19 stake-address derivation, used for the wallet path-2 signer binding,\n// requires the 28-byte BLAKE2b digest of the signer's Ed25519 public key.\n// The Cardano ledger encodes stake addresses as\n// `network_header_byte || Blake2b-224(stake_vk)`\n// per CIP-19, so this output length is fixed by spec.\nexport function blake2b224(input: Uint8Array): Uint8Array {\n return blake2b(input, { dkLen: 28 });\n}\n","import * as ed from '@noble/ed25519';\nimport { sha512 } from '@noble/hashes/sha2.js';\n\ned.hashes.sha512 = sha512;\n\n// Ed25519 group order L (= 2^252 + 27742317777372353535851937790883648493).\nconst L = ed.Point.CURVE().n;\n\nexport interface SignEd25519Opts {\n readonly seed: Uint8Array;\n readonly message: Uint8Array;\n}\n\nexport interface VerifyEd25519Opts {\n readonly publicKey: Uint8Array;\n readonly message: Uint8Array;\n readonly signature: Uint8Array;\n}\n\nexport interface GetPublicKeyEd25519Opts {\n readonly seed: Uint8Array;\n}\n\nexport function signEd25519(opts: SignEd25519Opts): Uint8Array {\n return ed.sign(opts.message, opts.seed);\n}\n\n// Little-endian 32-byte scalar → bigint.\nfunction leBytesToBigInt(bytes: Uint8Array): bigint {\n let value = 0n;\n for (let i = bytes.length - 1; i >= 0; i--) {\n value = (value << 8n) | BigInt(bytes[i]!);\n }\n return value;\n}\n\n// Strict (non-cofactored) Ed25519 verification per RFC 8032 §5.1.7, matching\n// libsodium/PyNaCl `crypto_sign_verify_detached` and ed25519-dalek\n// `verify_strict`. The cofactor-less check rejects every small-order /\n// torsion-component edge case in the C2SP/CCTV corpus, which noble's\n// `{ zip215: false }` mode does NOT (it remains cofactored: it checks\n// `[8]([S]B - [k]A - R) == 0`, accepting torsion components).\n//\n// The verification equation is the unscaled `[S]B == R + [k]A`, rewritten as\n// `[S]B - [k]A - R == identity`. We reject S >= L (non-canonical scalar) and\n// any small-order A or R up front, so a torsion component can never be smuggled\n// through the cofactor multiplication the cofactored variant performs.\nexport function verifyEd25519(opts: VerifyEd25519Opts): boolean {\n const { signature, message, publicKey } = opts;\n if (signature.length !== 64 || publicKey.length !== 32) return false;\n\n // S = LE(sig[32..64]); reject if not a canonical scalar (S >= L).\n const S = leBytesToBigInt(signature.subarray(32, 64));\n if (S >= L) return false;\n\n // Decode A (public key) and R (sig[0..32]) with the canonical (non-zip215)\n // point encoding; a non-canonical encoding throws and rejects.\n let A: ed.Point;\n let R: ed.Point;\n try {\n A = ed.Point.fromBytes(publicKey);\n R = ed.Point.fromBytes(signature.subarray(0, 32));\n } catch {\n return false;\n }\n\n // Reject small-order (cofactor-torsion) A or R: this is exactly the strictness\n // that distinguishes verify_strict from the cofactored check.\n if (A.isSmallOrder() || R.isSmallOrder()) return false;\n\n // k = SHA-512(R || A || M) reduced mod L.\n const k =\n leBytesToBigInt(ed.hash(concatBytes(signature.subarray(0, 32), publicKey, message))) % L;\n\n // Accept iff [S]B - [k]A - R == identity. `multiplyUnsafe` returns the\n // identity for a 0 scalar, but guard explicitly to avoid relying on that.\n const sB = S === 0n ? ed.Point.ZERO : ed.Point.BASE.multiplyUnsafe(S);\n const kA = k === 0n ? ed.Point.ZERO : A.multiplyUnsafe(k);\n return sB.subtract(kA).subtract(R).is0();\n}\n\nfunction concatBytes(...parts: Uint8Array[]): Uint8Array {\n let total = 0;\n for (const p of parts) total += p.length;\n const out = new Uint8Array(total);\n let offset = 0;\n for (const p of parts) {\n out.set(p, offset);\n offset += p.length;\n }\n return out;\n}\n\nexport function getPublicKeyEd25519(opts: GetPublicKeyEd25519Opts): Uint8Array {\n return ed.getPublicKey(opts.seed);\n}\n","// Isomorphic constant-time byte-equality. crypto-core is browser-safe by\n// design, so we cannot import `node:crypto.timingSafeEqual` — webpack rejects\n// the `node:` scheme in the browser bundle. A pure-JS XOR loop is constant-time\n// for equal-length inputs; length mismatch is a deliberate early-return (the\n// API surface itself leaks length, same as node's timingSafeEqual which throws).\nexport function compareCt(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n // Lengths are equal and `i` stays in-bounds, so both indexes are always\n // defined — no nullish guard is needed (and one would read as a guard for\n // an impossible case).\n for (let i = 0; i < a.length; i++) diff |= (a[i] as number) ^ (b[i] as number);\n return diff === 0;\n}\n","export type CoseVerifyErrorCode =\n | 'MALFORMED_SIG_COSE'\n | 'MALFORMED_SIG_COSE_SIGN1'\n | 'UNSUPPORTED_SIG_ALG'\n | 'KID_UNRESOLVED'\n | 'SIGNATURE_INVALID';\n\nexport class CoseVerifyError extends Error {\n readonly code: CoseVerifyErrorCode;\n\n constructor(code: CoseVerifyErrorCode, message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = 'CoseVerifyError';\n this.code = code;\n }\n}\n\nexport type CoseVerifyResult =\n | { ok: true; signerKey: Uint8Array; alg: number }\n | { ok: false; error: { code: CoseVerifyErrorCode; message: string } };\n","import {\n decodeCanonicalCbor,\n encodeCanonicalCbor,\n type CanonicalCborValue,\n} from '../cbor/canonical';\nimport { CanonicalCborError } from '../cbor/errors';\nimport { blake2b224 } from '../hash/blake2b-256';\nimport { signEd25519, verifyEd25519 } from '../sig/ed25519';\nimport { compareCt } from '../util/compare-ct';\n\nimport { CoseVerifyError, type CoseVerifyResult } from './errors';\n\nexport type CoseHeader = Map<number | string, unknown>;\n\n// Label 309 v1 domain separator embedded as a prefix on `Sig_structure[3]`\n// (`to_sign`). The separator is\n// NOT placed in `Sig_structure[2]` (`external_aad`) because CIP-30 `signData`\n// — the only realistic wallet-signing path on Cardano — explicitly forbids a\n// non-empty `external_aad`. Pinning the prefix into the payload preserves the\n// anti-replay property while keeping wallet-produced signatures byte-identical\n// to verifier-side recomputation.\nexport const CARDANO_POE_SIG_DOMAIN_PREFIX = 'cardano-poe-record-sig-v1' as const;\n// Composer path-2 wallet flow consumes the prefix bytes directly\n// to assemble `toSign = prefix || canonical_cbor(record_body)` BEFORE calling\n// `walletSignData` (the wallet's `signData()` receives this concatenation as\n// its `payload` argument verbatim per CIP-30). The bytes constant is exported\n// so a composer can build the input without re-encoding the prefix at every\n// call site.\nexport const CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES = new TextEncoder().encode(\n CARDANO_POE_SIG_DOMAIN_PREFIX,\n);\n\n// Fail-fast: the prefix length is byte-pinned at 25 UTF-8 bytes. A different\n// runtime encoding would silently break round-tripping\n// against the reference vectors.\nif (CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length !== 25) {\n throw new Error(\n `cardano-poe-record-sig-v1 prefix must encode to exactly 25 UTF-8 bytes, got ${CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length}`,\n );\n}\n\nconst EMPTY_BYTES = new Uint8Array(0);\n\nexport interface CoseSign1Decoded {\n readonly protectedHeader: CoseHeader;\n // preserved for Sig_structure reconstruction — never re-encode the decoded header map (RFC 9052 §4.4)\n readonly protectedBytes: Uint8Array;\n readonly unprotectedHeader: CoseHeader;\n readonly payload: Uint8Array | null;\n readonly signature: Uint8Array;\n}\n\nexport interface BuildSigStructureArgs {\n readonly context: 'Signature1';\n readonly bodyProtectedBytes: Uint8Array;\n readonly externalAad: Uint8Array;\n readonly payload: Uint8Array;\n}\n\n// Raw RFC 9052 §4.4 Sig_structure builder. General-purpose: callers control\n// `external_aad` and `payload` exactly. For Label 309 record signing use\n// `buildLabel309SigStructure` instead — it enforces the Label 309 record-signature invariants.\nexport function buildSigStructure(args: BuildSigStructureArgs): Uint8Array {\n return encodeCanonicalCbor([\n args.context,\n args.bodyProtectedBytes,\n args.externalAad,\n args.payload,\n ] as readonly CanonicalCborValue[]);\n}\n\nexport interface BuildLabel309SigStructureArgs {\n readonly bodyProtectedBytes: Uint8Array;\n // Canonical CBOR of the record body with `sigs` removed.\n readonly recordBodyCbor: Uint8Array;\n}\n\n// Label 309 v1 specialisation of `Sig_structure` (RFC 9052 §4.4 base structure):\n// to_sign = utf8(\"cardano-poe-record-sig-v1\") || canonical_cbor(record_body_minus_sigs)\n// Sig_structure = [ \"Signature1\", body_protected, h'' (empty), to_sign ]\n// Always forces `external_aad = h''` (empty bstr) — the CIP-30 wallet path\n// cannot carry a non-empty `external_aad`, so the domain separator lives in\n// `Sig_structure[3]` rather than `Sig_structure[2]`.\nexport function buildLabel309SigStructure(args: BuildLabel309SigStructureArgs): Uint8Array {\n const toSign = new Uint8Array(\n CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length + args.recordBodyCbor.length,\n );\n toSign.set(CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES, 0);\n toSign.set(args.recordBodyCbor, CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length);\n return buildSigStructure({\n context: 'Signature1',\n bodyProtectedBytes: args.bodyProtectedBytes,\n externalAad: EMPTY_BYTES,\n payload: toSign,\n });\n}\n\nexport interface EncodeCoseSign1Args {\n readonly protectedHeader: CoseHeader;\n readonly unprotectedHeader: CoseHeader;\n readonly payload: Uint8Array | null;\n readonly signature: Uint8Array;\n}\n\nexport function encodeCoseSign1(args: EncodeCoseSign1Args): Uint8Array {\n const protectedBytes =\n args.protectedHeader.size === 0\n ? EMPTY_BYTES\n : encodeCanonicalCbor(args.protectedHeader as CanonicalCborValue);\n return encodeCanonicalCbor([\n protectedBytes,\n args.unprotectedHeader as CanonicalCborValue,\n args.payload,\n args.signature,\n ] as readonly CanonicalCborValue[]);\n}\n\n// cbor2's decoder returns Map for integer-keyed maps but plain Object for empty\n// or string-keyed maps; normalise both representations to Map.\nfunction asCoseHeader(value: unknown): CoseHeader | null {\n if (value instanceof Map) return value as CoseHeader;\n if (value !== null && typeof value === 'object' && (value as object).constructor === Object) {\n return new Map(Object.entries(value as Record<string, unknown>));\n }\n return null;\n}\n\nexport function decodeCoseSign1(bytes: Uint8Array): CoseSign1Decoded {\n let arr: unknown;\n try {\n arr = decodeCanonicalCbor(bytes);\n } catch (cause) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'cose decode failed', { cause });\n }\n if (!Array.isArray(arr) || arr.length !== 4) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'expected 4-element array');\n }\n const [protectedBytesRaw, unprotectedRaw, payloadRaw, signatureRaw] = arr;\n if (!(protectedBytesRaw instanceof Uint8Array)) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'protected_bytes must be bytes');\n }\n const unprotectedHeader = asCoseHeader(unprotectedRaw);\n if (unprotectedHeader === null) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'unprotected header must be map');\n }\n if (payloadRaw !== null && !(payloadRaw instanceof Uint8Array)) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'payload must be bytes or null');\n }\n if (!(signatureRaw instanceof Uint8Array) || signatureRaw.length !== 64) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'signature must be 64 bytes');\n }\n let protectedHeader: CoseHeader;\n if (protectedBytesRaw.length === 0) {\n protectedHeader = new Map();\n } else {\n let decodedProtected: unknown;\n try {\n decodedProtected = decodeCanonicalCbor(protectedBytesRaw);\n } catch (cause) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'protected header decode failed', { cause });\n }\n const ph = asCoseHeader(decodedProtected);\n if (ph === null) {\n throw new CoseVerifyError('MALFORMED_SIG_COSE', 'protected header must decode to map');\n }\n // Empty protected header MUST encode as the single byte 0x40 (zero-length bstr),\n // not 0x41 0xA0 (a 1-byte bstr containing an empty CBOR map). RFC 9052 §3 +\n // Label 309 canonical-CBOR mandate.\n if (ph.size === 0) {\n throw new CoseVerifyError(\n 'MALFORMED_SIG_COSE',\n 'empty protected header must encode as 0x40 (zero-length bstr), not as an empty map',\n );\n }\n protectedHeader = ph;\n }\n return {\n protectedHeader,\n protectedBytes: protectedBytesRaw,\n unprotectedHeader,\n payload: payloadRaw,\n signature: signatureRaw,\n };\n}\n\nexport type CoseSign1BuildErrorCode = 'SIGNER_NOT_PROVIDED' | 'SIGNER_AND_SEED_BOTH_PROVIDED';\n\nexport class CoseSign1BuildError extends Error {\n readonly code: CoseSign1BuildErrorCode;\n\n constructor(code: CoseSign1BuildErrorCode, message: string) {\n super(message);\n this.name = 'CoseSign1BuildError';\n this.code = code;\n }\n}\n\nexport interface CoseSign1Label309BuildArgs {\n readonly protectedHeader: CoseHeader;\n readonly unprotectedHeader: CoseHeader;\n // Canonical CBOR of the record body with `sigs` removed. The\n // builder prepends the 25-byte UTF-8 domain prefix `cardano-poe-record-sig-v1`\n // internally — callers MUST NOT pre-concatenate it.\n readonly recordBodyCbor: Uint8Array;\n // EITHER the raw 32-byte Ed25519 seed (used by KAT tests, Python parity, and\n // the off-host signing helper) OR an injected signer closure that signs the\n // assembled Sig_structure bytes (composer-side use — keeps the private key\n // inside the unlock-store closure so it never escapes scope).\n // Exactly one of the two MUST be provided; mutual exclusion enforced at\n // runtime via CoseSign1BuildError.\n readonly signerSecretKey?: Uint8Array;\n readonly signer?: (sigStructureBytes: Uint8Array) => Uint8Array;\n}\n\n// Label 309 v1 record-signature builder:\n// 1. compute `to_sign = utf8(\"cardano-poe-record-sig-v1\") || recordBodyCbor`\n// 2. Sig_structure = [ \"Signature1\", bodyProtected, h'', to_sign ]\n// 3. Ed25519-sign Sig_structure (via seed OR injected closure)\n// 4. emit COSE_Sign1 with payload = CBOR null (detached signature, mandatory)\nexport function coseSign1Label309Build(args: CoseSign1Label309BuildArgs): Uint8Array {\n if (args.signerSecretKey === undefined && args.signer === undefined) {\n throw new CoseSign1BuildError(\n 'SIGNER_NOT_PROVIDED',\n 'coseSign1Label309Build requires either signerSecretKey or signer',\n );\n }\n if (args.signerSecretKey !== undefined && args.signer !== undefined) {\n throw new CoseSign1BuildError(\n 'SIGNER_AND_SEED_BOTH_PROVIDED',\n 'coseSign1Label309Build accepts signerSecretKey XOR signer (not both)',\n );\n }\n const protectedBytes =\n args.protectedHeader.size === 0\n ? EMPTY_BYTES\n : encodeCanonicalCbor(args.protectedHeader as CanonicalCborValue);\n const sigStructureBytes = buildLabel309SigStructure({\n bodyProtectedBytes: protectedBytes,\n recordBodyCbor: args.recordBodyCbor,\n });\n let signature: Uint8Array;\n if (args.signer !== undefined) {\n signature = args.signer(sigStructureBytes);\n if (!(signature instanceof Uint8Array) || signature.length !== 64) {\n throw new CoseSign1BuildError(\n 'SIGNER_NOT_PROVIDED',\n `injected signer must return a 64-byte Uint8Array; got ${signature instanceof Uint8Array ? `${signature.length}-byte Uint8Array` : typeof signature}`,\n );\n }\n } else {\n signature = signEd25519({ seed: args.signerSecretKey!, message: sigStructureBytes });\n }\n return encodeCoseSign1({\n protectedHeader: args.protectedHeader,\n unprotectedHeader: args.unprotectedHeader,\n payload: null,\n signature,\n });\n}\n\nexport interface CoseSign1Label309VerifyArgs {\n readonly message: Uint8Array;\n // Canonical CBOR of the record body with `sigs` removed (verifier-recomputed;\n // the 25-byte UTF-8 prefix is prepended internally — callers\n // MUST NOT pre-concatenate it).\n readonly detachedRecordBodyCbor: Uint8Array;\n // Optional out-of-band signer key (path-2 wallet path resolves the key from\n // `sigs[i].cose_key`). Path-1 records carry the 32-byte raw Ed25519 pubkey\n // in the protected header at label 4 (`kid`) and need no out-of-band hint.\n readonly expectedSignerKey?: Uint8Array;\n}\n\n// Label 309 v1 record-signature verifier:\n// - Decode COSE_Sign1\n// - Reject COSE_Sign1[2] != CBOR null (attached payload — including h'') as\n// MALFORMED_SIG_COSE_SIGN1\n// - Recompute to_sign = utf8(\"cardano-poe-record-sig-v1\") || detachedRecordBodyCbor\n// - Sig_structure = [ \"Signature1\", protectedBytes, h'', to_sign ]\n// - Strict Ed25519 verify (RFC 8032 §5.1.7 — `zip215: false` per ed25519.ts)\n//\n// The verifier does NOT accept an `externalAad` argument: Label 309 v1 pins\n// `external_aad = h''` and any deviation would either silently weaken the\n// domain separator or quietly accept malformed records. If a future CIP\n// revision re-enables external_aad, this helper takes a v-bump.\nexport function coseSign1Label309Verify(args: CoseSign1Label309VerifyArgs): CoseVerifyResult {\n let decoded: CoseSign1Decoded;\n try {\n decoded = decodeCoseSign1(args.message);\n } catch (e) {\n if (e instanceof CoseVerifyError) {\n return { ok: false, error: { code: e.code, message: 'errors.cose.malformed' } };\n }\n if (e instanceof CanonicalCborError) {\n return {\n ok: false,\n error: { code: 'MALFORMED_SIG_COSE', message: 'errors.cose.malformed_cbor' },\n };\n }\n throw e;\n }\n // Label 309 v1 mandate: COSE_Sign1[2] (payload field) MUST be CBOR `null` (0xF6).\n // Any non-null payload — including a zero-length byte string `h''` — MUST\n // be rejected as MALFORMED_SIG_COSE_SIGN1.\n if (decoded.payload !== null) {\n return {\n ok: false,\n error: {\n code: 'MALFORMED_SIG_COSE_SIGN1',\n message: 'errors.cose.attached_payload_forbidden',\n },\n };\n }\n const alg = decoded.protectedHeader.get(1);\n if (typeof alg !== 'number' || alg !== -8) {\n return {\n ok: false,\n error: { code: 'UNSUPPORTED_SIG_ALG', message: 'errors.cose.unsupported_alg' },\n };\n }\n const kidRaw = decoded.protectedHeader.get(4);\n let signerKey: Uint8Array | undefined;\n if (kidRaw instanceof Uint8Array && kidRaw.length === 32) {\n signerKey = kidRaw;\n } else if (args.expectedSignerKey instanceof Uint8Array && args.expectedSignerKey.length === 32) {\n signerKey = args.expectedSignerKey;\n }\n if (signerKey === undefined) {\n return {\n ok: false,\n error: { code: 'KID_UNRESOLVED', message: 'errors.cose.kid_unresolved' },\n };\n }\n // When both a protected-header kid AND an expectedSignerKey are provided,\n // require they agree (constant-time). A protected kid that disagrees with\n // the caller's out-of-band binding is a misuse, not a transient mismatch.\n if (\n kidRaw instanceof Uint8Array &&\n kidRaw.length === 32 &&\n args.expectedSignerKey instanceof Uint8Array &&\n args.expectedSignerKey.length === 32 &&\n !compareCt(kidRaw, args.expectedSignerKey)\n ) {\n return {\n ok: false,\n error: { code: 'KID_UNRESOLVED', message: 'errors.cose.kid_mismatch' },\n };\n }\n // CIP-8 `hashed = true` mode (the wallet-signed path-2 variant). The unprotected\n // header carries the literal text key `\"hashed\"` with boolean value `true`\n // (text-keyed CBOR maps decode to `Map<string, unknown>` via cbor2). When\n // set, both producer and verifier build `Sig_structure[3] = Blake2b-224(to_sign)`\n // (28-byte digest of the FULL `to_sign` payload including the 25-byte\n // domain prefix). When absent or false, the standard non-hashed path\n // applies unchanged.\n const hashedFlag = decoded.unprotectedHeader.get('hashed');\n let sigStructureBytes: Uint8Array;\n if (hashedFlag === true) {\n const toSign = new Uint8Array(\n CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length + args.detachedRecordBodyCbor.length,\n );\n toSign.set(CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES, 0);\n toSign.set(args.detachedRecordBodyCbor, CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length);\n const hashedPayload = blake2b224(toSign);\n sigStructureBytes = buildSigStructure({\n context: 'Signature1',\n bodyProtectedBytes: decoded.protectedBytes,\n externalAad: EMPTY_BYTES,\n payload: hashedPayload,\n });\n } else {\n sigStructureBytes = buildLabel309SigStructure({\n bodyProtectedBytes: decoded.protectedBytes,\n recordBodyCbor: args.detachedRecordBodyCbor,\n });\n }\n const valid = verifyEd25519({\n publicKey: signerKey,\n message: sigStructureBytes,\n signature: decoded.signature,\n });\n if (!valid) {\n return {\n ok: false,\n error: { code: 'SIGNATURE_INVALID', message: 'errors.cose.signature_invalid' },\n };\n }\n return { ok: true, signerKey, alg };\n}\n","// CIP-30 / RFC 9052 §7 COSE_Key extraction for the Ed25519 sig path.\n//\n// CIP-30 wallets that don't put a 32-byte raw Ed25519 pubkey in the COSE_Sign1\n// protected header instead deliver the signer key as a separate `cbor<COSE_Key>`\n// blob, surfaced in the Label 309 record under the top-level `signer_keys` field.\n// This helper decodes one such blob and returns the underlying 32-byte Ed25519\n// pubkey, or `null` when the blob is malformed, uses an unexpected key type /\n// curve, or has the wrong `x` length.\n//\n// The expected COSE_Key shape (RFC 9053 §7.2 + RFC 8152 §13):\n// {\n// 1 (kty): 1 // OKP\n// 3 (alg): -8 // EdDSA — OPTIONAL but if present MUST be -8\n// -1 (crv): 6 // Ed25519\n// -2 (x): <32 byte raw public key>\n// }\n\nimport { decodeCanonicalCbor } from '../cbor/canonical';\n\nconst COSE_KEY_LABEL_KTY = 1;\nconst COSE_KEY_LABEL_ALG = 3;\nconst COSE_KEY_LABEL_CRV = -1;\nconst COSE_KEY_LABEL_X = -2;\n\nconst KTY_OKP = 1;\nconst ALG_EDDSA = -8;\nconst CRV_ED25519 = 6;\n\nconst ED25519_PUBLIC_KEY_LENGTH = 32;\n\nfunction asMap(value: unknown): Map<unknown, unknown> | null {\n if (value instanceof Map) return value as Map<unknown, unknown>;\n if (value !== null && typeof value === 'object' && (value as object).constructor === Object) {\n return new Map(Object.entries(value as Record<string, unknown>));\n }\n return null;\n}\n\nexport function parseCoseKeyEd25519(blob: Uint8Array): Uint8Array | null {\n let decoded: unknown;\n try {\n decoded = decodeCanonicalCbor(blob);\n } catch {\n return null;\n }\n const map = asMap(decoded);\n if (map === null) return null;\n\n const kty = map.get(COSE_KEY_LABEL_KTY);\n if (typeof kty !== 'number' || kty !== KTY_OKP) return null;\n\n const crv = map.get(COSE_KEY_LABEL_CRV);\n if (typeof crv !== 'number' || crv !== CRV_ED25519) return null;\n\n if (map.has(COSE_KEY_LABEL_ALG)) {\n const alg = map.get(COSE_KEY_LABEL_ALG);\n if (typeof alg !== 'number' || alg !== ALG_EDDSA) return null;\n }\n\n const x = map.get(COSE_KEY_LABEL_X);\n if (!(x instanceof Uint8Array) || x.length !== ED25519_PUBLIC_KEY_LENGTH) return null;\n\n return x;\n}\n"]}
|
package/dist/index.cjs
CHANGED
|
@@ -383,7 +383,7 @@ function decodeCanonicalCbor(bytes) {
|
|
|
383
383
|
...cbor2.cdeDecodeOptions,
|
|
384
384
|
rejectStreaming: true,
|
|
385
385
|
rejectDuplicateKeys: true,
|
|
386
|
-
// A
|
|
386
|
+
// A Label 309 record carries integers, byte/text strings, arrays, maps and
|
|
387
387
|
// `null` — and nothing else. Without these rejections the major-type-7
|
|
388
388
|
// surface leaks into the decoder: a float16/32/64 that happens to hold an
|
|
389
389
|
// integral value (e.g. 1.0) silently decodes to the integer 1 and passes
|
|
@@ -443,7 +443,7 @@ function buildSigStructure(args) {
|
|
|
443
443
|
args.payload
|
|
444
444
|
]);
|
|
445
445
|
}
|
|
446
|
-
function
|
|
446
|
+
function buildLabel309SigStructure(args) {
|
|
447
447
|
const toSign = new Uint8Array(
|
|
448
448
|
CARDANO_POE_SIG_DOMAIN_PREFIX_BYTES.length + args.recordBodyCbor.length
|
|
449
449
|
);
|
|
@@ -534,21 +534,21 @@ var CoseSign1BuildError = class extends Error {
|
|
|
534
534
|
this.code = code;
|
|
535
535
|
}
|
|
536
536
|
};
|
|
537
|
-
function
|
|
537
|
+
function coseSign1Label309Build(args) {
|
|
538
538
|
if (args.signerSecretKey === void 0 && args.signer === void 0) {
|
|
539
539
|
throw new CoseSign1BuildError(
|
|
540
540
|
"SIGNER_NOT_PROVIDED",
|
|
541
|
-
"
|
|
541
|
+
"coseSign1Label309Build requires either signerSecretKey or signer"
|
|
542
542
|
);
|
|
543
543
|
}
|
|
544
544
|
if (args.signerSecretKey !== void 0 && args.signer !== void 0) {
|
|
545
545
|
throw new CoseSign1BuildError(
|
|
546
546
|
"SIGNER_AND_SEED_BOTH_PROVIDED",
|
|
547
|
-
"
|
|
547
|
+
"coseSign1Label309Build accepts signerSecretKey XOR signer (not both)"
|
|
548
548
|
);
|
|
549
549
|
}
|
|
550
550
|
const protectedBytes = args.protectedHeader.size === 0 ? EMPTY_BYTES : encodeCanonicalCbor(args.protectedHeader);
|
|
551
|
-
const sigStructureBytes =
|
|
551
|
+
const sigStructureBytes = buildLabel309SigStructure({
|
|
552
552
|
bodyProtectedBytes: protectedBytes,
|
|
553
553
|
recordBodyCbor: args.recordBodyCbor
|
|
554
554
|
});
|
|
@@ -571,7 +571,7 @@ function coseSign1Cip309Build(args) {
|
|
|
571
571
|
signature
|
|
572
572
|
});
|
|
573
573
|
}
|
|
574
|
-
function
|
|
574
|
+
function coseSign1Label309Verify(args) {
|
|
575
575
|
let decoded;
|
|
576
576
|
try {
|
|
577
577
|
decoded = decodeCoseSign1(args.message);
|
|
@@ -638,7 +638,7 @@ function coseSign1Cip309Verify(args) {
|
|
|
638
638
|
payload: hashedPayload
|
|
639
639
|
});
|
|
640
640
|
} else {
|
|
641
|
-
sigStructureBytes =
|
|
641
|
+
sigStructureBytes = buildLabel309SigStructure({
|
|
642
642
|
bodyProtectedBytes: decoded.protectedBytes,
|
|
643
643
|
recordBodyCbor: args.detachedRecordBodyCbor
|
|
644
644
|
});
|
|
@@ -1804,14 +1804,14 @@ exports.bech32DecodeNoLimit = bech32DecodeNoLimit;
|
|
|
1804
1804
|
exports.bech32EncodeNoLimit = bech32EncodeNoLimit;
|
|
1805
1805
|
exports.blake2b224 = blake2b224;
|
|
1806
1806
|
exports.blake2b256 = blake2b256;
|
|
1807
|
-
exports.
|
|
1807
|
+
exports.buildLabel309SigStructure = buildLabel309SigStructure;
|
|
1808
1808
|
exports.buildSigStructure = buildSigStructure;
|
|
1809
1809
|
exports.chacha20Poly1305Decrypt = chacha20Poly1305Decrypt;
|
|
1810
1810
|
exports.chacha20Poly1305Encrypt = chacha20Poly1305Encrypt;
|
|
1811
1811
|
exports.chunkKemCt = chunkKemCt;
|
|
1812
1812
|
exports.compareCt = compareCt;
|
|
1813
|
-
exports.
|
|
1814
|
-
exports.
|
|
1813
|
+
exports.coseSign1Label309Build = coseSign1Label309Build;
|
|
1814
|
+
exports.coseSign1Label309Verify = coseSign1Label309Verify;
|
|
1815
1815
|
exports.decodeCanonicalCbor = decodeCanonicalCbor;
|
|
1816
1816
|
exports.decodeCbor = decodeCbor;
|
|
1817
1817
|
exports.decodeCoseSign1 = decodeCoseSign1;
|