Expand description
§vitaminc-prf
vitaminc-prf provides a serde-style API for deriving structured,
domain-separated pseudorandom values. Inputs cross backend boundaries in
Protected containers, maps bind their keys into the derivation context, and
backend output is always awaitable so local and remote batched implementations
share one interface.
This crate defines only the abstraction: the PrfValue,
Prf, and
PrfKeyInit
traits, context and encoding domains, and the visitor machinery. It contains
no cryptography. Concrete backends live in their own crates; the local
HMAC-SHA256 backend is vitaminc-hmac,
and its documentation carries runnable end-to-end examples.
Key ownership lives in exactly one place. PrfKeyInit constructs a backend
from key material taken by value, so the key moves into the backend and is
wiped when the backend drops. Every Prf derivation method then borrows the
backend (&self): a derivation is a pure function of the key and the input,
so nothing is consumed and one instance serves any number of derivations
without being cloned.
Every protected leaf carries an explicit PrfEncoding
domain. Built-in text, bytes, and fixed-width integers are separated even when
their byte representations happen to match. Custom leaf implementations must
provide a stable, namespaced encoding identifier, preventing accidental
untagged derivation.
§Implementing PrfValue for a struct
Struct implementations describe their fields with a map driver. The final visitor receives resolved child nodes, so each field can produce a different owned output while a deferred backend still executes the structure as one batch.
use vitaminc_prf::{
BlockVisitor, IntoPrfContext, MapAccess, MapPrf, Prf,
PrfValue, PrfVisitor, PrfVisitorError, SeqAccess,
};
struct User {
email: String,
aliases: Vec<String>,
}
impl PrfValue for User {
fn prf_visit_with_context<'a, P, V, C>(
self,
prf: &P,
context: C,
visitor: V,
) -> P::Ok<V::Value>
where
P: Prf,
V: PrfVisitor<P::Block, P::Passthrough>,
C: IntoPrfContext<'a>,
{
let context = context.into_prf_context().into_owned();
prf.prf_map(Some(2))
.prf_entry("email", self.email, context.clone())
.prf_entry("aliases", self.aliases, context)
.end(visitor)
}
}
struct BlockListVisitor;
impl<P> PrfVisitor<[u8; 32], P> for BlockListVisitor {
type Value = Vec<[u8; 32]>;
fn visit_seq(self, seq: SeqAccess<[u8; 32], P>) -> Result<Self::Value, PrfVisitorError> {
seq.map(|node| node.visit(BlockVisitor)).collect()
}
}
#[derive(Debug, PartialEq, Eq)]
struct UserTerms {
email: [u8; 32],
aliases: Vec<[u8; 32]>,
}
struct UserTermsVisitor;
impl<P> PrfVisitor<[u8; 32], P> for UserTermsVisitor {
type Value = UserTerms;
fn visit_map(
self,
mut map: MapAccess<[u8; 32], P>,
) -> Result<Self::Value, PrfVisitorError> {
let (email_key, email) = map.next_entry().ok_or(PrfVisitorError::InvalidValue)?;
let (aliases_key, aliases) = map.next_entry().ok_or(PrfVisitorError::InvalidValue)?;
if email_key != "email" || aliases_key != "aliases" || map.next_entry().is_some() {
return Err(PrfVisitorError::InvalidValue);
}
Ok(UserTerms {
email: email.visit(BlockVisitor)?,
aliases: aliases.visit(BlockListVisitor)?,
})
}
}Executing the derivation requires a backend; with vitaminc-hmac in
scope the value above resolves through
user.prf_visit_with_context(&prf, "tenant/acme/users/v1", UserTermsVisitor).await.
Structs§
- Block
Visitor - Visitor that returns one raw backend block.
- Context
- The canonical encoding of a context, as bytes.
- MapAccess
- Pull-style access to resolved string-keyed map children.
- Passthrough
- Marks an explicitly non-secret value that should pass through unchanged.
- PrfEncoding
- A stable semantic domain for encoding a protected PRF leaf.
- Ready
Prf - An immediately available, awaitable PRF result.
- Resolved
Visitor - SeqAccess
- Pull-style access to resolved sequence children.
Enums§
- Context
Piece - One part of a context, or a list of parts.
- PrfBuild
Error - Errors detected while a structured PRF program is being built.
- PrfError
- A structured PRF failure.
- PrfVisitor
Error - Errors produced when a visitor is used with the wrong resolved shape.
- Resolved
Prf - A fully resolved node supplied to sequence and map visitors.
Traits§
- Into
Context - Types that describe themselves as a context.
- Into
PrfContext - Types that can be used as the domain-separation context of a PRF derivation.
- MapPrf
- Map driver. See
SeqPrffor the ownership convention. - Prf
- Backend for structured pseudorandom derivation.
- PrfKey
Init - Construction of a
Prfbackend from key material. - PrfValue
- A type that can describe its structure to a
Prfbackend. - PrfVisitor
- Interprets a resolved PRF result.
- SeqPrf
- Sequence driver. A driver is owned by one caller for the length of one
derivation, so its builder methods consume and return
Self; it borrows the backend it was created from.
Type Aliases§
- PrfContext
Deprecated - The context a PRF derives under. Kept as a name for the transition; it
is
Context.