UNPKG

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

Version:

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

363 lines (355 loc) 12.9 kB
/** * BitManager - Low-level bitstring manipulation for W3C Bitstring Status Lists * * Manages a packed bitstring where credentials are mapped to bit positions. * Each credential gets a fixed-width status entry at position: credentialIndex * statusSize. * * Features: * - Direct bit access without entry tracking * - Automatic buffer expansion in 16KB blocks * - MSB-first bit ordering within bytes * - Zero-initialized status values * * @example * ```typescript * const manager = new BitManager({ statusSize: 2 }) * manager.setStatus(0, 3) // Sets 2 bits at position 0 * console.log(manager.getStatus(0)) // Returns 3 * console.log(manager.getStatus(1)) // Returns 0 (unset) * ``` */ declare class BitManager { private bits; private readonly statusSize; /** * Creates a new BitManager instance * * @param options.statusSize - Bits per credential status (default: 1, max: 31) * @param options.buffer - Existing buffer for decoding * @param options.initialSize - Initial buffer size in bytes (default: 16KB) */ constructor(options?: { statusSize?: number; buffer?: Uint8Array; initialSize?: number; }); /** * Gets the status value for a credential * * @param credentialIndex - Non-negative credential identifier * @returns Status value (0 to 2^statusSize - 1) */ getStatus(credentialIndex: number): number; /** * Sets the status value for a credential * * @param credentialIndex - Non-negative credential identifier * @param status - Status value (0 to 2^statusSize - 1) * @throws {StatusRangeError} If status exceeds maximum value for statusSize */ setStatus(credentialIndex: number, status: number): void; /** * Returns current buffer trimmed to actual data size * * @returns Copy of buffer containing only written data */ toBuffer(): Uint8Array; /** * Gets the uniform status size for all entries * * @returns Number of bits per status entry */ getStatusSize(): number; /** * Gets the total buffer size in bytes * * @returns Buffer size in bytes */ getBufferLength(): number; /** * Reads status bits from buffer starting at bit position * * @param startBit - Starting bit position * @returns Decoded status value */ private readStatusBits; /** * Writes status bits to buffer starting at bit position * * @param startBit - Starting bit position * @param status - Status value to write */ private writeStatusBits; /** * Ensures buffer can hold the specified number of bytes * Grows in bitstring-sized chunks for better memory efficiency * * @param requiredBytes - Minimum bytes needed */ private ensureBufferCanHold; } /** * StatusList - High-level W3C Bitstring Status List implementation * * Provides a complete implementation of the W3C Bitstring Status List v1.0 specification. * Manages a compressed bitstring where each credential has a uniform-width status entry. * * Features: * - W3C compliant 16KB minimum bitstring size * - GZIP compression with multibase encoding (u-prefix) * - Uniform status size for all entries in a list * - Direct credential access without explicit entry creation * - Efficient ISIZE-based length calculation * * @example * ```typescript * // Create a status list for revocation (1-bit per credential) * const list = new StatusList({ statusSize: 1 }) * list.setStatus(42, 1) // Mark credential 42 as revoked * * const encoded = await list.encode() // Get compressed, encoded string * const decoded = await StatusList.decode({ encodedList: encoded, statusSize: 1 }) * console.log(decoded.getStatus(42)) // Returns 1 * ``` */ declare class BitstreamStatusList { private readonly bitManager; private readonly statusSize; /** * Creates a new StatusList instance * * @param options.buffer - Existing bitstring buffer for decoding (uncompressed) * @param options.initialSize - Initial buffer size in bytes (default: 16KB) * @param options.statusSize - Uniform bit width for all entries (default: 1) */ constructor(options?: { buffer?: Uint8Array; initialSize?: number; statusSize?: number; }); /** * Gets the status value for a credential * * @param credentialIndex - Credential identifier * @returns Status value (0 to 2^statusSize - 1) */ getStatus(credentialIndex: number): number; /** * Sets the status value for a credential * * @param credentialIndex - Credential identifier * @param status - Status value (0 to 2^statusSize - 1) */ setStatus(credentialIndex: number, status: number): void; /** * Returns the uniform status size (bit width) for all entries */ getStatusSize(): number; /** * Encodes the status list into a W3C compliant compressed string * * Process: * 1. Get current bitstring buffer * 2. Pad to minimum 16KB (W3C requirement) * 3. GZIP compress the padded buffer * 4. Base64url encode with 'u' prefix (multibase) * * @returns Promise resolving to u-prefixed compressed string */ encode(): Promise<string>; /** * Decodes a W3C compliant status list string into a StatusList instance * * @param options.encodedList - u-prefixed, gzip-compressed base64url string * @param options.statusSize - Uniform bit width used during encoding (default: 1) * @returns Promise resolving to new StatusList instance * @throws {MalformedValueError} If format is invalid * @throws {StatusListLengthError} If size requirements not met */ static decode(options: { encodedList: string; statusSize?: number; }): Promise<BitstreamStatusList>; /** * Gets the maximum number of entries this decoded status list can hold * * @returns Maximum number of entries based on current buffer size */ getLength(): number; /** * Efficiently calculates the maximum number of entries in an encoded status list * Uses GZIP ISIZE field to determine uncompressed size without full decompression * * @param encodedList - u-prefixed, gzip-compressed base64url string * @param statusSize - Uniform bit width used during encoding * @returns Maximum number of entries (uncompressed_bits / statusSize) * @throws {MalformedValueError} If format is invalid */ static getStatusListLength(encodedList: string, statusSize: number): number; /** * Pads buffer to W3C minimum size requirement (16KB) * * @param buffer - Source buffer to pad * @returns Padded buffer (original if already >= 16KB) */ private padToMinimumSize; } /** * Central type definitions for the Bitstring Status List library * Based on W3C Bitstring Status List v1.0 specification */ type BitstringStatusPurpose = 'revocation' | 'suspension' | 'refresh' | 'message' | string; interface BitstringStatusListEntry { id?: string; type: 'BitstringStatusListEntry'; statusPurpose: 'revocation' | 'suspension' | 'message' | string; statusListIndex: string; statusListCredential: string; statusSize?: number; statusMessage?: StatusMessage[]; statusReference?: string | string[]; } interface BitstringStatusListCredentialSubject { id: string; type: 'BitstringStatusList'; statusPurpose: 'revocation' | 'suspension' | 'message' | string | string[]; encodedList: string; ttl?: number; } type AdditionalClaims = Record<string, any>; type BitstringStatusListCredentialUnsigned = AdditionalClaims & { '@context': string[]; id: string; issuer: string | IIssuer; type: string[]; credentialSubject: BitstringStatusListCredentialSubject; validFrom?: string; validUntil?: string; }; interface IIssuer { id: string; [x: string]: any; } type CredentialStatus = BitstringStatusListEntry | BitstringStatusListEntry[]; interface CredentialWithStatus { '@context': string[]; id: string; type: string[]; issuer: string | IIssuer; validFrom?: string; validUntil?: string; credentialStatus?: CredentialStatus; credentialSubject: { id: string; type: string; [key: string]: any; }; } interface CheckStatusOptions { credential: CredentialWithStatus; getStatusListCredential: (url: string) => Promise<BitstringStatusListCredentialUnsigned>; } interface VerificationResult { verified: boolean; status: number; statusMessage?: StatusMessage; error?: Error; } interface StatusMessage { id: string; message: string; } /** * High-level credential creation functions for W3C Bitstring Status Lists * * Provides convenient functions to create compliant BitstringStatusListCredentials * according to the W3C Bitstring Status List v1.0 specification. */ /** * Creates a W3C compliant BitstringStatusListCredential with an empty status list * * The created credential contains an empty status list that can be referenced by * other credentials through their credentialStatus.statusListCredential property. * Individual credential statuses are managed separately by updating the status list * and republishing the credential. * * @example * ```typescript * // Create a revocation list for single-bit status (revoked/not revoked) * const credential = await createStatusListCredential({ * id: 'https://issuer.example/status/1', * issuer: 'https://issuer.example', * statusPurpose: 'revocation' * }) * * // Create a message list with 4-bit status codes * const messageList = await createStatusListCredential({ * id: 'https://issuer.example/status/messages', * issuer: { id: 'https://issuer.example', name: 'Example Issuer' }, * statusPurpose: 'message', * statusSize: 4, * validUntil: new Date('2025-12-31') * }) * ``` * * @param options.id - Unique identifier for the status list credential * @param options.issuer - Issuer identifier (string) or issuer object with id * @param options.statusSize - Uniform bit width for status entries (default: 1) * @param options.statusPurpose - Purpose(s) of the status list (e.g., 'revocation', 'suspension') * @param options.validFrom - Optional start of validity period * @param options.validUntil - Optional end of validity period * @param options.ttl - Optional time-to-live in milliseconds * @returns Promise resolving to unsigned BitstringStatusListCredential */ declare function createStatusListCredential(options: { id: string; issuer: string | IIssuer; statusSize?: number; statusList?: BitstreamStatusList; statusPurpose: string | string[]; validFrom?: Date; validUntil?: Date; ttl?: number; }): Promise<BitstringStatusListCredentialUnsigned>; /** * W3C Bitstring Status List credential verification logic * * Implements the complete W3C Bitstring Status List v1.0 verification algorithm * including status purpose validation, temporal validity checks, and minimum * bitstring length requirements. */ /** * Checks the status of a credential against its referenced status list * * Implements the W3C Bitstring Status List verification algorithm: * 1. Validates credential structure and extracts BitstringStatusListEntry * 2. Retrieves and validates the status list credential * 3. Checks temporal validity (validFrom/validUntil) * 4. Validates status purpose matching * 5. Verifies minimum bitstring length requirements * 6. Decodes status list and retrieves credential status * 7. Determines verification result based on status purpose * * @example * ```typescript * const result = await checkStatus({ * credential: someCredentialWithStatus, * getStatusListCredential: async (url) => { * const response = await fetch(url) * return response.json() * } * }) * * if (result.verified) { * console.log('Credential is valid') * } else { * console.log('Credential failed:', result.error?.message) * } * ``` * * @param options.credential - The credential to check status for * @param options.getStatusListCredential - Function to retrieve status list credential by URL * @returns Promise resolving to verification result with status details */ declare function checkStatus(options: CheckStatusOptions): Promise<VerificationResult>; export { type AdditionalClaims, BitManager, BitstreamStatusList, type BitstringStatusListCredentialSubject, type BitstringStatusListCredentialUnsigned, type BitstringStatusListEntry, type BitstringStatusPurpose, type CheckStatusOptions, type CredentialStatus, type CredentialWithStatus, type IIssuer, type StatusMessage, type VerificationResult, checkStatus, createStatusListCredential };