Loading vLEI.wiki
Fetching knowledge base...
Fetching knowledge base...
This comprehensive explanation has been generated from 112 GitHub source documents. All source documents are searchable here.
Last updated: October 7, 2025
This content is meant to be consumed by AI agents via MCP. Click here to get the MCP configuration.
Note: In rare cases it may contain LLM hallucinations.
For authoritative documentation, please consult the official GLEIF vLEI trainings and the ToIP Glossary.
A framing code is a specialized CESR encoding element that delineates the number of characters (in text domain) or bytes (in binary domain) that can be extracted atomically from a stream, enabling self-framing primitives and groups to be parsed without external delimiters or schemas.
A framing code (also called frame-code, FRAME-CODE, derivation code, or count code) is a fundamental component of CESR (Composable Event Streaming Representation) that provides self-describing type and length information for cryptographic primitives and data structures in KERI streams. Framing codes enable self-framing - the property where each encoded element contains sufficient metadata to determine its own boundaries without requiring external schemas, delimiters, or context.
Formally, a framing code is a prefix attached to encoded data that specifies:
Framing codes are the mechanism that makes CESR streams composable - enabling lossless round-trip conversion between text and binary domains while maintaining the ability to parse individual primitives from concatenated streams.
Framing codes serve multiple critical functions in the KERI ecosystem:
Stream Parsing: Enable parsers to process CESR streams without prior knowledge of content structure. By reading the framing code, a parser immediately knows the primitive type and can extract exactly the right number of characters/bytes.
Composability: Support the fundamental CESR property that T(cat(b[k])) = cat(T(b[k])) - the transformation of concatenated primitives equals the concatenation of individually transformed primitives. This requires that primitive boundaries align on 24-bit boundaries, which framing codes ensure.
Self-Description: Make cryptographic material self-describing by embedding algorithm information directly in the encoding. A verifier receiving a CESR-encoded signature knows which algorithm to use for verification without external configuration.
Pipelining: Enable efficient stream processing where multiple primitives can be multiplexed into complex streams and de-multiplexed back without ambiguity, supporting high-bandwidth applications.
Framing codes fall into several categories:
Basic Primitive Codes: Single-character or multi-character codes for fixed-size cryptographic primitives (keys, digests, signatures). Example: B indicates an Ed25519 non-transferable prefix public key (44 characters in text domain).
Variable-Length Codes: Codes that include explicit length information for variable-size data. Example: 4B## where ## represents two Base64 characters encoding the length in quadlets.
Count Codes (also called group framing codes): Special codes that specify the number of primitives in a group, enabling hierarchical composition. Example: -AAB indicates an event source seal triple attachment.
Version Codes: Special count codes that specify which CESR code table version is active for a stream section.
Framing codes themselves are not cryptographic primitives - they are metadata that describes cryptographic primitives. However, they have critical security properties:
Framing codes cryptographically bind the algorithm specification to the encoded material. When a primitive is encoded with derivation code E, this creates an immutable association with the Blake3-256 algorithm. Any attempt to interpret the material with a different algorithm will fail verification.
The self-describing nature of framing codes prevents certain classes of attacks:
Algorithm Substitution: An attacker cannot substitute a weaker algorithm because the framing code explicitly specifies which algorithm was used.
Length Manipulation: The framing code's length specification prevents buffer overflow attacks or truncation attacks by precisely defining boundaries.
Type Confusion: Different primitive types have distinct framing codes, preventing type confusion vulnerabilities where one primitive type is misinterpreted as another.
Framing codes do not perform cryptographic operations themselves - they describe the operations that were performed. The actual cryptographic strength comes from the algorithms they reference (Ed25519, Blake3-256, etc.) and the key material they frame.
A CESR-encoded primitive with framing code follows this structure:
[Framing Code][Value]
Where:
In the text domain, framing codes use Base64 URL-safe characters (A-Z, a-z, 0-9, -, _). The code length varies:
1-character codes: For small fixed-size primitives with pad size 1
B for Ed25519 public key2-character codes: For primitives with pad size 0 or 2, or for special purposes
0B for Ed25519 signature4-character codes: For large fixed-size primitives
1AAA for ECDSA secp256k1 public keyVariable-length codes: Include length information
4BAA for a 0-length byte string (code indicates lead size 0)5AABAA-A for a 2-character string with lead size 1In the binary domain, framing codes are more compact:
1-byte codes: Most common primitives
2-byte codes: Extended primitive set
Multi-byte codes: For count codes and variable-length primitives
All CESR primitives must align on 24-bit boundaries because:
Framing codes achieve this through pre-padding (lead bytes) before Base64 conversion. The pad size calculation is:
ps = (3 - (N mod 3)) mod 3
Where ps is pad size and N is raw binary length in bytes.
Common framing codes in KERI:
Keys:
B: Ed25519 non-transferable prefix (44 chars)D: Ed25519 public key (44 chars)1AAA: ECDSA secp256k1 non-transferable prefix (48 chars)Digests:
E: Blake3-256 (44 chars)F: Blake2b-256 (44 chars)H: SHA3-256 (44 chars)0D: Blake3-512 (88 chars)Signatures:
0B: Ed25519 signature (88 chars)0C: ECDSA secp256k1 signature (88 chars)Count Codes:
-AAB: Event source seal triple-CAB: Witness signature couple5AAA: Version string count codeFraming codes appear throughout KEL structures:
Inception Events: The i field contains an AID with a framing code indicating the key type. Example: BHt9Kw8oUgfB2kiyoj65B2VE5fZLr87S5MJP3l4JeRwC uses code B for Ed25519.
Rotation Events: The k field (current keys) and n field (next key digests) use framing codes. The n field typically uses digest codes like E for Blake3-256 digests of pre-rotated keys.
Signatures: All event signatures are attached with framing codes. The -AAB count code indicates a signature attachment follows, with the actual signature using code 0B for Ed25519.
Event Digests: The d field (SAID) uses digest framing codes to indicate the hash algorithm used for the event's self-addressing identifier.
Framing codes enable ACDC features:
Compact Disclosure: ACDCs can be compacted by replacing field values with their SAIDs. The SAID's framing code indicates the digest algorithm, enabling verification when the full value is later disclosed.
Issuer Identification: The i field (issuer AID) uses framing codes to specify the issuer's key type.
Schema References: The s field can contain a SAID with framing code indicating the schema's digest algorithm.
Chaining: The e field (edges) contains SAIDs of other ACDCs, with framing codes enabling verification of the chain.
Framing codes enable stream processing:
Cold Start Parsing: When a parser encounters a CESR stream after reboot, it reads the first framing code to determine how to parse the first primitive, then continues sequentially.
Interleaved Serialization: Special count codes mark boundaries between CESR and other formats (JSON, CBOR, MGPK), enabling mixed-format streams.
Hierarchical Composition: Group framing codes enable nested structures where groups of primitives are treated as higher-level primitives.
Verifying CESR-encoded primitives:
For signatures:
0B for Ed25519)D for Ed25519 key)Count codes are specialized framing codes that specify the number of primitives in a group rather than framing a single primitive. They enable:
Example: -AAB indicates a couple (2 primitives) follows, specifically an event source seal triple format.
The term derivation code is often used interchangeably with framing code, particularly when referring to codes that specify cryptographic algorithms. The "derivation" refers to how the primitive was derived (which algorithm was used).
Version codes are special count codes that specify which CESR code table version is active. They enable:
All CESR primitives are qualified by definition - they include a framing code (proem) that qualifies the primitive with algorithm information. This qualification is what makes CESR primitives self-describing.
Implementations must maintain code tables mapping framing codes to:
The CESR specification defines multiple code tables:
Efficient CESR parsing:
This enables streaming parsing where primitives are processed as they arrive without buffering entire messages.
Framing codes enable robust error detection:
Unknown codes: If a code is not in the table, the primitive is invalid Length mismatches: If the stream ends before the specified length, it's truncated Alignment errors: If primitives don't align on 24-bit boundaries, the encoding is invalid
Framing codes enable optimizations:
Zero-copy parsing: In binary domain, primitives can be referenced in place without copying Parallel processing: Independent primitives can be processed concurrently Incremental verification: Signatures can be verified as they arrive without buffering
Framing codes are essential to CESR's composability property. The formal requirement:
T(cat(b[k])) = cat(T(b[k])) for all k
B(cat(t[k])) = cat(B(t[k])) for all k
This means:
Framing codes enable this by ensuring primitive boundaries align on 24-bit boundaries, preventing bit-level dependencies between adjacent primitives.
Traditional encodings use external framing:
{} and , delimitersCESR uses self-framing via framing codes:
This enables CESR's unique combination of human-readable text encoding and efficient binary encoding with full round-trip composability.
Framing codes make CESR streams sniffable - a parser can automatically detect:
This is achieved through careful code design where the first few bits/characters unambiguously identify the format and version.
Implementations must maintain comprehensive code tables mapping framing codes to primitive specifications. The CESR specification defines multiple tables:
Each table entry must specify:
Efficient CESR parsing requires a state machine approach:
For streaming applications, implement incremental parsing where primitives are processed as they arrive without buffering entire messages.
Robust implementations must handle:
Unknown framing codes: If a code is not in the active code table, the primitive is invalid. Implementations should either reject the stream or skip to the next recognizable boundary.
Truncated streams: If the stream ends before the specified primitive length, the stream is incomplete. Implementations should buffer and wait for more data in streaming contexts.
Alignment violations: If primitives don't align on 24-bit boundaries, the encoding is invalid. This indicates either corruption or non-CESR data.
Version mismatches: If a version code specifies an unsupported CESR version, implementations should either reject the stream or attempt to parse using the closest supported version.
Zero-copy parsing: In binary domain, implementations can reference primitives in place without copying bytes, significantly improving performance for large streams.
Parallel processing: Independent primitives can be verified concurrently. Group framing codes enable identifying parallelizable sections.
Incremental verification: Signatures can be verified as they arrive without buffering entire messages, reducing memory requirements.
Code table caching: Frequently used code lookups should be cached to avoid repeated table searches.
When implementing CESR framing codes:
Strict compliance: Follow the CESR specification exactly for code assignments and lengths to ensure interoperability.
Version support: Implement version code handling to support multiple CESR versions as the protocol evolves.
Mixed-format streams: Support interleaved serialization where CESR is mixed with JSON, CBOR, or MGPK using special count codes as boundaries.
Text/binary duality: Ensure implementations can handle both text and binary domain representations and convert between them losslessly.
Comprehensive testing should cover:
Round-trip conversion: Verify that primitives can be converted from text to binary and back without loss.
Concatenation composability: Verify that concatenated primitives can be converted as a group and produce the same result as individual conversion.
Boundary conditions: Test primitives at minimum and maximum sizes, and with all possible pad sizes (0, 1, 2).
Error cases: Test handling of unknown codes, truncated streams, and alignment violations.
Performance: Benchmark parsing speed for large streams with many primitives.