cesride — Rust CESR Primitives
Overview
cesride is the Rust implementation of CESR (Composable Event Streaming Representation) primitives for the KERI ecosystem. It provides typed wrappers around cryptographic material (keys, signatures, digests) with qualified CESR encoding (qb64/qb2), plus SAD serialization (Serder/Creder), counter-based stream framing, and threshold logic.
Key design: every primitive implements the Matter trait (or Indexer for indexed signatures), giving uniform qb64() /qb2() /raw() /code() access. Construction follows a consistent pattern across all types.
Companion skills: For CESR encoding theory and code tables, see cesr. For KERI event semantics, see spec. For ACDC credential structure, see acdc.
Quick Reference
Type Purpose Trait Reference
Verfer
Public verification key Matter cesr-primitives.md
Signer
Private signing key (auto-zeroized) Matter cesr-primitives.md
Diger
Cryptographic digest Matter cesr-primitives.md
Cigar
Unindexed signature Matter cesr-primitives.md
Siger
Indexed signature (multisig) Indexer cesr-primitives.md
Salter
Key derivation salt (auto-zeroized) Matter cesr-primitives.md
Saider
Self-Addressing Identifier (SAID) Matter cesr-primitives.md
Prefixer
KERI identifier prefix Matter cesr-primitives.md
Seqner
Sequence number (16-byte) Matter cesr-primitives.md
Number
Auto-sized unsigned integer Matter cesr-primitives.md
Dater
ISO 8601 timestamp Matter cesr-primitives.md
Bexter
Base64 text (Bext trait) Matter cesr-primitives.md
Pather
SAD path resolver (Bext trait) Matter cesr-primitives.md
Serder
KERI event serializer Sadder sad-serialization.md
Creder
ACDC credential serializer Sadder sad-serialization.md
Counter
Group framing construct — sad-serialization.md
Tholder
Signing threshold logic — threshold-utils.md
Import Guide
// Core traits use cesride::core::matter::Matter; use cesride::core::indexer::Indexer; use cesride::core::sadder::Sadder; use cesride::core::bexter::Bext;
// Primitives use cesride::core::{Verfer, Diger, Signer, Salter, Cigar, Siger}; use cesride::core::{Saider, Prefixer, Seqner, Number, Dater, Bexter, Pather};
// Serialization use cesride::core::{Serder, Creder, Counter}; use cesride::core::common::{versify, deversify, sniff};
// Code tables use cesride::core::matter::tables as MatterCodex; use cesride::core::indexer::tables as IndexerCodex; use cesride::core::counter::tables as CounterCodex;
// Data model use cesride::data::{Value, dat}; use cesride::error::{Error, Result};
// Crypto (raw bytes, no CESR) use cesride::crypto::{sign, hash, salt, csprng};
Reference Files
File Contents Size
references/cesr-primitives.md All 13 typed Matter/Indexer primitives — constructors, methods, valid codes 11KB
references/sad-serialization.md Sadder/Serder/Creder traits, Counter API, Ids/Ilkage constants 4KB
references/crypto.md Raw cryptographic operations — sign/verify, hash, stretch, CSPRNG 5KB
references/data-errors.md Value enum, data::Number, Error (28 variants), dat! macro 7KB
references/threshold-utils.md Tholder (weighted/unweighted), B64 conversion utilities 6KB
Common Constructor Pattern
All Matter primitives share the same constructor family:
Type::new(/* type-specific params */, code, raw, qb64b, qb64, qb2) -> Result<Self> Type::new_with_raw(raw, code) -> Result<Self> Type::new_with_qb64(qb64) -> Result<Self> Type::new_with_qb64b(qb64b) -> Result<Self> Type::new_with_qb2(qb2) -> Result<Self>
Construction dispatches: first non-None wins in order: raw → qb64b → qb64 → qb2.
Usage Patterns
- Generate Key Pair and Sign
let signer = Signer::new_with_defaults(Some(true), None)?; // Ed25519, transferable let verfer = signer.verfer(); let cigar = signer.sign_unindexed(message)?; assert!(verfer.verify(&cigar.raw(), message)?);
- Derive Keys from Salt
let salter = Salter::new_with_defaults(Some("low"))?; let signers = salter.signers(Some(3), None, Some("icp"), None, None, None, None)?;
- Create and Verify SAID
let (saider, saidified_sad) = Saider::saidify(&sad, None, None, None, None)?; assert!(saider.verify(&saidified_sad, None, None, None, None, None)?);
- Build KERI Event
let serder = Serder::new_with_ked(&ked, None, None)?; let said = serder.said()?; let pre = serder.pre()?; let raw = serder.raw();
- Check Threshold Satisfaction
let tholder = Tholder::new_with_sith(&dat!([["1/2", "1/2"], ["1"]]))?; assert!(tholder.satisfy(&[0, 1, 2])?);
Anti-Patterns
DON'T: Store Signer or Salter raw bytes — they auto-zeroize on drop. DO: Use Salter::signers() with hierarchical paths for deterministic key derivation.
DON'T: Use Cigar for multisig — it has no index information. DO: Use Siger with sign_indexed() for multisig coordination.
DON'T: Construct version strings manually. DO: Use versify() /deversify() for version string handling.
DON'T: Confuse data::Number (JSON numeric wrapper) with core::Number (CESR primitive). DO: Use core::Number for CESR-encoded integers, data::Number for JSON values.
DON'T: Use Counter as a Matter primitive — it has its own encoding scheme. DO: Use Counter::new_with_code_and_count() for stream framing.