UNPKG

@4sure-tech/vc-bitstring-status-lists

Version:

TypeScript library for W3C Bitstring Status List v1.0 specification - privacy-preserving credential status management

1 lines 40.9 kB
{"version":3,"sources":["../src/index.ts","../src/utils/assertions.ts","../src/status-list/errors.ts","../src/bit-manager/BitManager.ts","../src/utils/base64.ts","../src/status-list/BitstreamStatusList.ts","../src/credential/create.ts","../src/credential/verify.ts"],"sourcesContent":["// Core Classes\nexport {BitManager} from './bit-manager/BitManager'\nexport {BitstreamStatusList} from './status-list/BitstreamStatusList'\n\n// High-Level Functions\nexport {createStatusListCredential} from './credential/create'\nexport {checkStatus} from './credential/verify'\n\n// Types\nexport type {\n StatusMessage,\n BitstringStatusPurpose,\n BitstringStatusListEntry,\n BitstringStatusListCredentialSubject,\n BitstringStatusListCredentialUnsigned,\n IIssuer,\n CredentialStatus,\n CredentialWithStatus,\n CheckStatusOptions,\n VerificationResult,\n AdditionalClaims\n} from './types'\n","/**\n * Runtime type guards and assertion utilities\n * Throws descriptive TypeError exceptions on validation failure\n */\n\nexport function assert(condition: boolean, message: string): void {\n if (!condition) {\n throw new TypeError(message)\n }\n}\n\nexport function assertIsNumber(value: any, name: string): void {\n if (typeof value !== 'number' || isNaN(value)) {\n throw new TypeError(`${name} must be a number, got ${typeof value}`)\n }\n}\n\nexport function assertIsPositiveInteger(value: any, name: string): void {\n assertIsNumber(value, name)\n if (!Number.isInteger(value) || value <= 0) {\n throw new TypeError(`${name} must be a positive integer, got ${value}`)\n }\n}\n\nexport function assertIsNonNegativeInteger(value: any, name: string): void {\n assertIsNumber(value, name)\n if (!Number.isInteger(value) || value < 0) {\n throw new TypeError(`${name} must be a non-negative integer, got ${value}`)\n }\n}\n\nexport function assertIsString(value: any, name: string): void {\n if (typeof value !== 'string') {\n throw new TypeError(`${name} must be a string, got ${typeof value}`)\n }\n}\n\nexport function assertIsObject(value: any, name: string): void {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new TypeError(`${name} must be an object, got ${typeof value}`)\n }\n}\n\nexport function assertIsUint8Array(value: any, name: string): void {\n if (!(value instanceof Uint8Array)) {\n throw new TypeError(`${name} must be a Uint8Array, got ${typeof value}`)\n }\n}\n","// errors.ts\nexport class BitstringStatusListError extends Error {\n public readonly type: string\n public readonly code: string\n\n constructor(type: string, code: string, message: string) {\n super(message)\n this.name = 'BitstringStatusListError'\n this.type = `https://www.w3.org/ns/credentials/status-list#${type}`\n this.code = code\n }\n}\n\nexport class StatusListLengthError extends BitstringStatusListError {\n constructor(message: string) {\n super('STATUS_LIST_LENGTH_ERROR', 'STATUS_LIST_LENGTH_ERROR', message)\n }\n}\n\nexport class StatusRangeError extends BitstringStatusListError {\n constructor(message: string) {\n super('RANGE_ERROR', 'RANGE_ERROR', message)\n }\n}\n\nexport class MalformedValueError extends BitstringStatusListError {\n constructor(message: string) {\n super('MALFORMED_VALUE_ERROR', 'MALFORMED_VALUE_ERROR', message)\n }\n}\n\nexport class StatusRetrievalError extends BitstringStatusListError {\n constructor(message: string) {\n super('STATUS_RETRIEVAL_ERROR', 'STATUS_RETRIEVAL_ERROR', message)\n }\n}\n\nexport class StatusVerificationError extends BitstringStatusListError {\n constructor(message: string) {\n super('STATUS_VERIFICATION_ERROR', 'STATUS_VERIFICATION_ERROR', message)\n }\n}\n","import {assertIsNonNegativeInteger, assertIsPositiveInteger} from \"../utils/assertions\"\nimport {StatusRangeError} from \"../status-list/errors\";\n\nconst LIST_BLOCK_SIZE = 16384 // 16KB\n\n/**\n * BitManager - Low-level bitstring manipulation for W3C Bitstring Status Lists\n *\n * Manages a packed bitstring where credentials are mapped to bit positions.\n * Each credential gets a fixed-width status entry at position: credentialIndex * statusSize.\n *\n * Features:\n * - Direct bit access without entry tracking\n * - Automatic buffer expansion in 16KB blocks\n * - MSB-first bit ordering within bytes\n * - Zero-initialized status values\n *\n * @example\n * ```typescript\n * const manager = new BitManager({ statusSize: 2 })\n * manager.setStatus(0, 3) // Sets 2 bits at position 0\n * console.log(manager.getStatus(0)) // Returns 3\n * console.log(manager.getStatus(1)) // Returns 0 (unset)\n * ```\n */\nexport class BitManager {\n private bits: Uint8Array\n private readonly statusSize: number\n\n /**\n * Creates a new BitManager instance\n *\n * @param options.statusSize - Bits per credential status (default: 1, max: 31)\n * @param options.buffer - Existing buffer for decoding\n * @param options.initialSize - Initial buffer size in bytes (default: 16KB)\n */\n constructor(options: {\n statusSize?: number\n buffer?: Uint8Array\n initialSize?: number\n } = {}) {\n const {statusSize = 1, buffer, initialSize = LIST_BLOCK_SIZE} = options\n\n assertIsPositiveInteger(statusSize, 'statusSize')\n\n // Guard against JavaScript bitwise operation overflow (which is insane for this use case, but it's the real limit.)\n if (statusSize > 30) {\n throw new StatusRangeError(`statusSize ${statusSize} exceeds maximum supported value of 30 bits`)\n }\n\n this.statusSize = statusSize\n this.bits = buffer ? new Uint8Array(buffer) : new Uint8Array(initialSize)\n }\n\n /**\n * Gets the status value for a credential\n *\n * @param credentialIndex - Non-negative credential identifier\n * @returns Status value (0 to 2^statusSize - 1)\n */\n getStatus(credentialIndex: number): number {\n assertIsNonNegativeInteger(credentialIndex, 'credentialIndex')\n\n // Check if index exceeds reasonable bounds\n const maxIndex = Math.floor(this.bits.length * 8 / this.statusSize)\n if (credentialIndex >= maxIndex) {\n throw new StatusRangeError(`credentialIndex ${credentialIndex} exceeds buffer bounds`)\n }\n\n const startBit = credentialIndex * this.statusSize\n return this.readStatusBits(startBit)\n }\n\n /**\n * Sets the status value for a credential\n *\n * @param credentialIndex - Non-negative credential identifier\n * @param status - Status value (0 to 2^statusSize - 1)\n * @throws {StatusRangeError} If status exceeds maximum value for statusSize\n */\n setStatus(credentialIndex: number, status: number): void {\n assertIsNonNegativeInteger(credentialIndex, 'credentialIndex')\n assertIsNonNegativeInteger(status, 'status')\n\n const maxValue = (1 << this.statusSize) - 1\n if (status > maxValue) {\n throw new StatusRangeError(`Status ${status} exceeds maximum value ${maxValue} for ${this.statusSize} bits`)\n }\n\n const startBit = credentialIndex * this.statusSize\n this.writeStatusBits(startBit, status)\n }\n\n /**\n * Returns current buffer trimmed to actual data size\n *\n * @returns Copy of buffer containing only written data\n */\n toBuffer(): Uint8Array {\n // search backwards from the end for non-zero bytes\n let lastNonZeroByte = -1\n for (let i = this.bits.length - 1; i >= 0; i--) {\n if (this.bits[i] !== 0) {\n lastNonZeroByte = i\n break\n }\n }\n\n if (lastNonZeroByte === -1) {\n return new Uint8Array([])\n }\n\n return this.bits.slice(0, lastNonZeroByte + 1)\n }\n\n\n /**\n * Gets the uniform status size for all entries\n *\n * @returns Number of bits per status entry\n */\n getStatusSize(): number {\n return this.statusSize\n }\n\n\n /**\n * Gets the total buffer size in bytes\n *\n * @returns Buffer size in bytes\n */\n getBufferLength(): number {\n return this.bits.length\n }\n\n /**\n * Reads status bits from buffer starting at bit position\n *\n * @param startBit - Starting bit position\n * @returns Decoded status value\n */\n private readStatusBits(startBit: number): number {\n let status = 0\n\n for (let i = 0; i < this.statusSize; i++) {\n const bitIndex = startBit + i\n const byteIndex = Math.floor(bitIndex / 8)\n const bitOffset = bitIndex % 8\n\n if (byteIndex >= this.bits.length) {\n continue\n }\n\n const bit = (this.bits[byteIndex] >> (7 - bitOffset)) & 1\n // MSB of status value should be leftmost bit\n status |= bit << (this.statusSize - i - 1)\n }\n\n return status\n }\n\n /**\n * Writes status bits to buffer starting at bit position\n *\n * @param startBit - Starting bit position\n * @param status - Status value to write\n */\n private writeStatusBits(startBit: number, status: number): void {\n for (let i = 0; i < this.statusSize; i++) {\n const bitIndex = startBit + i\n const byteIndex = Math.floor(bitIndex / 8)\n const bitOffset = bitIndex % 8\n\n this.ensureBufferCanHold(byteIndex + 1)\n\n // MSB of status value should be leftmost bit\n const bit = (status >> (this.statusSize - i - 1)) & 1\n\n if (bit === 1) {\n this.bits[byteIndex] |= (1 << (7 - bitOffset))\n } else {\n this.bits[byteIndex] &= ~(1 << (7 - bitOffset))\n }\n }\n }\n\n /**\n * Ensures buffer can hold the specified number of bytes\n * Grows in bitstring-sized chunks for better memory efficiency\n *\n * @param requiredBytes - Minimum bytes needed\n */\n private ensureBufferCanHold(requiredBytes: number): void {\n if (requiredBytes > this.bits.length) {\n // Calculate growth in bitstring-sized chunks rather than fixed 16KB blocks\n const bitsNeeded = requiredBytes * 8\n const entriesNeeded = Math.ceil(bitsNeeded / this.statusSize)\n const optimalBits = entriesNeeded * this.statusSize\n const optimalBytes = Math.ceil(optimalBits / 8)\n\n // Still ensure minimum block size for reasonable growth\n const minGrowthBytes = Math.max(optimalBytes, LIST_BLOCK_SIZE)\n const blocksNeeded = Math.ceil(minGrowthBytes / LIST_BLOCK_SIZE)\n const newSize = blocksNeeded * LIST_BLOCK_SIZE\n\n const newBuffer = new Uint8Array(newSize)\n newBuffer.set(this.bits)\n this.bits = newBuffer\n }\n }\n}\n","import * as u8a from 'uint8arrays'\n\nexport function bytesToBase64url(b: Uint8Array): string {\n return u8a.toString(b, 'base64url')\n}\n\nexport function base64urlToBytes(s: string): Uint8Array {\n return u8a.fromString(s, 'base64url')\n}","/**\n * StatusList - High-level W3C Bitstring Status List implementation\n *\n * Provides a complete implementation of the W3C Bitstring Status List v1.0 specification.\n * Manages a compressed bitstring where each credential has a uniform-width status entry.\n *\n * Features:\n * - W3C compliant 16KB minimum bitstring size\n * - GZIP compression with multibase encoding (u-prefix)\n * - Uniform status size for all entries in a list\n * - Direct credential access without explicit entry creation\n * - Efficient ISIZE-based length calculation\n *\n * @example\n * ```typescript\n * // Create a status list for revocation (1-bit per credential)\n * const list = new StatusList({ statusSize: 1 })\n * list.setStatus(42, 1) // Mark credential 42 as revoked\n *\n * const encoded = await list.encode() // Get compressed, encoded string\n * const decoded = await StatusList.decode({ encodedList: encoded, statusSize: 1 })\n * console.log(decoded.getStatus(42)) // Returns 1\n * ```\n */\n\nimport {BitManager} from '../bit-manager/BitManager'\nimport {base64urlToBytes, bytesToBase64url} from '../utils/base64'\nimport {assertIsPositiveInteger, assertIsString} from '../utils/assertions'\nimport pako from 'pako'\nimport {MalformedValueError, StatusListLengthError} from \"./errors\";\n\n/** W3C specification minimum bitstring size */\nconst MIN_BITSTRING_SIZE_BYTES = 16384 // 16KB (131,072 bits)\nconst MIN_BITSTRING_SIZE_BITS = 131072\n\nexport class BitstreamStatusList {\n private readonly bitManager: BitManager\n private readonly statusSize: number\n\n /**\n * Creates a new StatusList instance\n *\n * @param options.buffer - Existing bitstring buffer for decoding (uncompressed)\n * @param options.initialSize - Initial buffer size in bytes (default: 16KB)\n * @param options.statusSize - Uniform bit width for all entries (default: 1)\n */\n constructor(options: {\n buffer?: Uint8Array\n initialSize?: number\n statusSize?: number\n } = {}) {\n const {buffer, initialSize, statusSize = 1} = options\n assertIsPositiveInteger(statusSize, 'statusSize')\n\n this.statusSize = statusSize\n this.bitManager = new BitManager({statusSize, buffer, initialSize})\n }\n\n /**\n * Gets the status value for a credential\n *\n * @param credentialIndex - Credential identifier\n * @returns Status value (0 to 2^statusSize - 1)\n */\n getStatus(credentialIndex: number): number {\n return this.bitManager.getStatus(credentialIndex)\n }\n\n /**\n * Sets the status value for a credential\n *\n * @param credentialIndex - Credential identifier\n * @param status - Status value (0 to 2^statusSize - 1)\n */\n setStatus(credentialIndex: number, status: number): void {\n this.bitManager.setStatus(credentialIndex, status)\n }\n\n /**\n * Returns the uniform status size (bit width) for all entries\n */\n getStatusSize(): number {\n return this.statusSize\n }\n\n /**\n * Encodes the status list into a W3C compliant compressed string\n *\n * Process:\n * 1. Get current bitstring buffer\n * 2. Pad to minimum 16KB (W3C requirement)\n * 3. GZIP compress the padded buffer\n * 4. Base64url encode with 'u' prefix (multibase)\n *\n * @returns Promise resolving to u-prefixed compressed string\n */\n async encode(): Promise<string> {\n const buffer = this.bitManager.toBuffer()\n const paddedBuffer = this.padToMinimumSize(buffer)\n const compressed = pako.gzip(paddedBuffer)\n\n return `u${bytesToBase64url(compressed)}`\n }\n\n /**\n * Decodes a W3C compliant status list string into a StatusList instance\n *\n * @param options.encodedList - u-prefixed, gzip-compressed base64url string\n * @param options.statusSize - Uniform bit width used during encoding (default: 1)\n * @returns Promise resolving to new StatusList instance\n * @throws {MalformedValueError} If format is invalid\n * @throws {StatusListLengthError} If size requirements not met\n */\n static async decode(options: {\n encodedList: string\n statusSize?: number\n }): Promise<BitstreamStatusList> {\n const {encodedList, statusSize = 1} = options\n\n assertIsString(encodedList, 'encodedList')\n assertIsPositiveInteger(statusSize, 'statusSize')\n\n // Validate multibase prefix\n if (!encodedList.startsWith('u')) {\n throw new MalformedValueError('encodedList must start with lowercase \"u\" prefix')\n }\n\n // Validate base64url alphabet and no padding\n const base64urlPart = encodedList.slice(1)\n if (!/^[A-Za-z0-9_-]+$/.test(base64urlPart)) {\n throw new MalformedValueError('encodedList contains invalid base64url characters or padding')\n }\n\n let compressed: Uint8Array\n let buffer: Uint8Array\n\n try {\n // Decode multibase\n compressed = base64urlToBytes(base64urlPart)\n // Decompress\n buffer = pako.ungzip(compressed)\n } catch (error) {\n throw new MalformedValueError(`Failed to decode or decompress encodedList: ${error.message}`)\n }\n\n // Enforce W3C minimum size requirement\n if (buffer.length < MIN_BITSTRING_SIZE_BYTES) {\n throw new StatusListLengthError(\n `Status list must be at least ${MIN_BITSTRING_SIZE_BYTES} bytes (16KB), got ${buffer.length}`\n )\n }\n\n // W3C spec step 9: validate minimum entries based on statusSize\n const totalBits = buffer.length * 8\n const availableEntries = Math.floor(totalBits / statusSize)\n const minimumEntries = Math.floor(MIN_BITSTRING_SIZE_BITS / statusSize)\n\n if (availableEntries < minimumEntries) {\n throw new StatusListLengthError(\n `Status list must support at least ${minimumEntries} entries for statusSize ${statusSize}, got ${availableEntries}`\n )\n }\n\n return new BitstreamStatusList({buffer, statusSize})\n }\n\n /**\n * Gets the maximum number of entries this decoded status list can hold\n *\n * @returns Maximum number of entries based on current buffer size\n */\n getLength(): number {\n const totalBits = this.bitManager.getBufferLength() * 8\n return Math.floor(totalBits / this.statusSize)\n }\n\n /**\n * Efficiently calculates the maximum number of entries in an encoded status list\n * Uses GZIP ISIZE field to determine uncompressed size without full decompression\n *\n * @param encodedList - u-prefixed, gzip-compressed base64url string\n * @param statusSize - Uniform bit width used during encoding\n * @returns Maximum number of entries (uncompressed_bits / statusSize)\n * @throws {MalformedValueError} If format is invalid\n */\n static getStatusListLength(encodedList: string, statusSize: number): number {\n assertIsString(encodedList, 'encodedList')\n assertIsPositiveInteger(statusSize, 'statusSize')\n\n // Validate multibase prefix\n if (!encodedList.startsWith('u')) {\n throw new MalformedValueError('encodedList must start with lowercase \"u\" prefix')\n }\n\n // Validate base64url alphabet and no padding\n const base64urlPart = encodedList.slice(1)\n if (!/^[A-Za-z0-9_-]+$/.test(base64urlPart)) {\n throw new MalformedValueError('encodedList contains invalid base64url characters or padding')\n }\n\n let compressed: Uint8Array\n try {\n compressed = base64urlToBytes(base64urlPart)\n } catch (error) {\n throw new MalformedValueError(`Failed to decode base64url: ${error.message}`)\n }\n\n if (compressed.length < 4) {\n throw new MalformedValueError('Invalid gzip data: too short to contain ISIZE field')\n }\n\n // Read ISIZE (last 4 bytes of gzip data, little-endian)\n const isizeOffset = compressed.byteOffset + compressed.length - 4\n const view = new DataView(compressed.buffer, isizeOffset, 4)\n const uncompressedBytes = view.getUint32(0, true)\n\n // Convert bytes to total available entries\n const totalBits = uncompressedBytes * 8\n return Math.floor(totalBits / statusSize)\n }\n\n /**\n * Pads buffer to W3C minimum size requirement (16KB)\n *\n * @param buffer - Source buffer to pad\n * @returns Padded buffer (original if already >= 16KB)\n */\n private padToMinimumSize(buffer: Uint8Array): Uint8Array {\n if (buffer.length >= MIN_BITSTRING_SIZE_BYTES) {\n return buffer\n }\n\n return Uint8Array.from({length: MIN_BITSTRING_SIZE_BYTES}, (_, i) => buffer[i] || 0)\n }\n}\n","/**\n * High-level credential creation functions for W3C Bitstring Status Lists\n *\n * Provides convenient functions to create compliant BitstringStatusListCredentials\n * according to the W3C Bitstring Status List v1.0 specification.\n */\n\nimport {BitstreamStatusList} from '../status-list/BitstreamStatusList'\nimport {BitstringStatusListCredentialSubject, BitstringStatusListCredentialUnsigned, IIssuer} from '../types'\n\n/**\n * Creates a W3C compliant BitstringStatusListCredential with an empty status list\n *\n * The created credential contains an empty status list that can be referenced by\n * other credentials through their credentialStatus.statusListCredential property.\n * Individual credential statuses are managed separately by updating the status list\n * and republishing the credential.\n *\n * @example\n * ```typescript\n * // Create a revocation list for single-bit status (revoked/not revoked)\n * const credential = await createStatusListCredential({\n * id: 'https://issuer.example/status/1',\n * issuer: 'https://issuer.example',\n * statusPurpose: 'revocation'\n * })\n *\n * // Create a message list with 4-bit status codes\n * const messageList = await createStatusListCredential({\n * id: 'https://issuer.example/status/messages',\n * issuer: { id: 'https://issuer.example', name: 'Example Issuer' },\n * statusPurpose: 'message',\n * statusSize: 4,\n * validUntil: new Date('2025-12-31')\n * })\n * ```\n *\n * @param options.id - Unique identifier for the status list credential\n * @param options.issuer - Issuer identifier (string) or issuer object with id\n * @param options.statusSize - Uniform bit width for status entries (default: 1)\n * @param options.statusPurpose - Purpose(s) of the status list (e.g., 'revocation', 'suspension')\n * @param options.validFrom - Optional start of validity period\n * @param options.validUntil - Optional end of validity period\n * @param options.ttl - Optional time-to-live in milliseconds\n * @returns Promise resolving to unsigned BitstringStatusListCredential\n */\nexport async function createStatusListCredential(options: {\n id: string\n issuer: string | IIssuer\n statusSize?: number\n statusList?: BitstreamStatusList\n statusPurpose: string | string[]\n validFrom?: Date\n validUntil?: Date\n ttl?: number\n}): Promise<BitstringStatusListCredentialUnsigned> {\n const {\n id,\n issuer,\n statusSize = 1,\n statusList,\n statusPurpose,\n validFrom,\n validUntil,\n ttl\n } = options\n\n // Create empty status list with specified statusSize\n const encodedList = await (statusList ?? new BitstreamStatusList({statusSize})).encode()\n\n // Build credential subject according to W3C spec\n const credentialSubject: BitstringStatusListCredentialSubject = {\n id: `${id}#list`,\n type: 'BitstringStatusList',\n statusPurpose,\n encodedList,\n ...(ttl && {ttl})\n }\n\n // Build the complete credential with W3C contexts\n const credential: BitstringStatusListCredentialUnsigned = {\n '@context': [\n 'https://www.w3.org/ns/credentials/v2', // Core VC context\n 'https://www.w3.org/ns/credentials/status/v1' // Status list context\n ],\n id,\n type: ['VerifiableCredential', 'BitstringStatusListCredential'],\n issuer,\n credentialSubject,\n ...(validFrom && {validFrom: validFrom.toISOString()}),\n ...(validUntil && {validUntil: validUntil.toISOString()})\n }\n\n return credential\n}","/**\n * W3C Bitstring Status List credential verification logic\n *\n * Implements the complete W3C Bitstring Status List v1.0 verification algorithm\n * including status purpose validation, temporal validity checks, and minimum\n * bitstring length requirements.\n */\n\nimport {BitstreamStatusList} from '../status-list/BitstreamStatusList'\nimport {BitstringStatusListEntry, CheckStatusOptions, StatusMessage, VerificationResult} from '../types'\nimport {assertIsObject} from '../utils/assertions'\n\n/** W3C minimum bitstring size in bits */\nconst MIN_BITSTRING_SIZE_BITS = 131072 // 16KB * 8\n\n/**\n * Checks the status of a credential against its referenced status list\n *\n * Implements the W3C Bitstring Status List verification algorithm:\n * 1. Validates credential structure and extracts BitstringStatusListEntry\n * 2. Retrieves and validates the status list credential\n * 3. Checks temporal validity (validFrom/validUntil)\n * 4. Validates status purpose matching\n * 5. Verifies minimum bitstring length requirements\n * 6. Decodes status list and retrieves credential status\n * 7. Determines verification result based on status purpose\n *\n * @example\n * ```typescript\n * const result = await checkStatus({\n * credential: someCredentialWithStatus,\n * getStatusListCredential: async (url) => {\n * const response = await fetch(url)\n * return response.json()\n * }\n * })\n *\n * if (result.verified) {\n * console.log('Credential is valid')\n * } else {\n * console.log('Credential failed:', result.error?.message)\n * }\n * ```\n *\n * @param options.credential - The credential to check status for\n * @param options.getStatusListCredential - Function to retrieve status list credential by URL\n * @returns Promise resolving to verification result with status details\n */\nexport async function checkStatus(options: CheckStatusOptions): Promise<VerificationResult> {\n try {\n const {credential, getStatusListCredential} = options\n\n // Validate input credential structure\n assertIsObject(credential, 'credential')\n\n if (!credential.credentialStatus) {\n return Promise.reject(new Error('No credentialStatus found in credential'))\n }\n\n // Extract BitstringStatusListEntry from credential status\n const entry = extractBitstringStatusEntry(credential.credentialStatus)\n if (!entry) {\n throw new Error('No BitstringStatusListEntry found in credentialStatus')\n }\n\n // Retrieve the status list credential\n const listCredential = await getStatusListCredential(entry.statusListCredential)\n\n // Validate temporal constraints\n validateTemporalValidity(listCredential)\n\n // Validate status purpose matching (W3C requirement)\n validateStatusPurposeAndSize(entry, listCredential)\n\n // Decode status list and validate minimum size\n const statusSize = entry.statusSize || 1\n const statusList = await BitstreamStatusList.decode({\n encodedList: listCredential.credentialSubject.encodedList,\n statusSize\n })\n\n\n // Verify W3C minimum bitstring length requirement\n validateMinimumBitstringLength(listCredential.credentialSubject.encodedList, statusSize)\n\n // Retrieve the actual status value\n const statusIndex = parseInt(entry.statusListIndex, 10)\n const status = statusList.getStatus(statusIndex)\n\n // Find corresponding status message if available\n const statusMessage = findStatusMessage(entry, status)\n\n // Determine verification result based on status purpose\n const verified = determineVerificationResult(entry.statusPurpose, status)\n\n return {\n verified,\n status,\n statusMessage\n }\n\n } catch (error) {\n return {\n verified: false,\n status: -1,\n error: error instanceof Error ? error : new Error(String(error))\n }\n }\n}\n\n/**\n * Extracts BitstringStatusListEntry from credential status\n * Handles both single entry and array of entries\n */\nfunction extractBitstringStatusEntry(\n credentialStatus: any\n): BitstringStatusListEntry | null {\n const statusEntries = Array.isArray(credentialStatus)\n ? credentialStatus\n : [credentialStatus]\n\n return statusEntries.find(entry => entry.type === 'BitstringStatusListEntry') || null\n}\n\n/**\n * Validates temporal validity of the status list credential\n * Checks validFrom and validUntil against current time\n */\nfunction validateTemporalValidity(listCredential: any): void {\n const now = new Date()\n\n if (listCredential.validFrom && new Date(listCredential.validFrom) > now) {\n throw new Error('Status list credential is not yet valid')\n }\n\n if (listCredential.validUntil && new Date(listCredential.validUntil) < now) {\n throw new Error('Status list credential has expired')\n }\n}\n\n/**\n * Validates that the entry's statusPurpose matches the list credential's purpose(s)\n * Implements W3C specification requirement for purpose matching\n */\nfunction validateStatusPurposeAndSize(\n entry: BitstringStatusListEntry,\n listCredential: any\n): void {\n const listStatusPurpose = listCredential.credentialSubject.statusPurpose\n const purposes = Array.isArray(listStatusPurpose) ? listStatusPurpose : [listStatusPurpose]\n\n if (!purposes.includes(entry.statusPurpose)) {\n throw new Error(\n `Status purpose '${entry.statusPurpose}' does not match any purpose in status list credential: ${purposes.join(', ')}`\n )\n }\n\n const statusSize = entry.statusSize || 1\n if ( listCredential.credentialSubject.statusSize !== statusSize) {\n throw new Error(`StatusSize mismatch: expected ${statusSize}, got from credentialSubject ${listCredential.credentialSubject.statusSize}`)\n }\n\n}\n\n/**\n * Validates that the bitstring meets W3C minimum length requirements\n * Uses efficient ISIZE-based calculation to avoid full decompression\n */\nfunction validateMinimumBitstringLength(encodedList: string, statusSize: number): void {\n const totalEntries = BitstreamStatusList.getStatusListLength(encodedList, statusSize)\n const minEntries = MIN_BITSTRING_SIZE_BITS / statusSize\n\n if (totalEntries < minEntries) {\n throw new Error(\n `Status list length error: bitstring must support at least ${minEntries} entries for statusSize ${statusSize}`\n )\n }\n}\n\n/**\n * Finds the corresponding status message for a given status value\n * Returns undefined if no matching message found\n */\nfunction findStatusMessage(\n entry: BitstringStatusListEntry,\n status: number\n): StatusMessage | undefined {\n if (!entry.statusMessage) {\n return undefined\n }\n\n const statusHex = `0x${status.toString(16)}`\n return entry.statusMessage.find(msg => msg.id === statusHex)\n}\n\n/**\n * Determines the verification result based on status purpose and value\n *\n * For 'revocation' and 'suspension': 0 = valid, non-zero = invalid\n * For other purposes: defaults to valid (assumes status is informational)\n */\nfunction determineVerificationResult(statusPurpose: string, status: number): boolean {\n if (statusPurpose === 'revocation' || statusPurpose === 'suspension') {\n return status === 0 // 0 means not revoked/suspended\n }\n\n // For other purposes (e.g., 'message'), default to valid\n // The status value provides information but doesn't affect validity\n return true\n}"],"mappings":"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","names":["pako","MIN_BITSTRING_SIZE_BITS"]}