Module crypto/digest

crypto/digest
Stability: unstable — the trait works and is exercised generically (`tests/crypto/digest.test.yo` hashes through a `where(D <: Digest)` bound and checks `digest_size` / `block_size`), but it is deliberately the minimum HMAC needed and two shape questions are open. There is no `reset`, so generic code cannot reuse a hasher and must build a new one per message; and `finish_bytes` does not CONSUME the hasher (Yo has no by-value `self` for a `ref` type here), so the trait cannot express "finalise exactly once" the way RustCrypto's `Digest::finalize(self)` does — every implementor's `finish` is single-use by convention, and the convention is documented rather than enforced. Freezing needs both calls made. Adding a method with a default (as `finish_hex` already is) stays additive; adding a required one does not. — stable modules only change additively; this one may still change.

The streaming Digest trait — one interface over Sha256 / Sha512 / Sha1 / Md5 (plans/archive/STD_API_AUDIT.md §7 P0 item 7).

The trait speaks ArrayList(u8) for the digest so one type covers every algorithm (the per-type inherent finish() keeps its fixed-size Array(u8, N) for callers that want it). new and the sizes are statics/constants of the implementor, which is what lets generic code — hmac (std/crypto/hmac.yo) is the flagship — construct and drive any hasher through a where(D <: Digest) bound.

Stability

unstable — the trait works and is exercised generically (tests/crypto/digest.test.yo hashes through a where(D <: Digest) bound and checks digest_size / block_size), but it is deliberately the minimum HMAC needed and two shape questions are open. There is no reset, so generic code cannot reuse a hasher and must build a new one per message; and finish_bytes does not CONSUME the hasher (Yo has no by-value self for a ref type here), so the trait cannot express "finalise exactly once" the way RustCrypto's Digest::finalize(self) does — every implementor's finish is single-use by convention, and the convention is documented rather than enforced. Freezing needs both calls made. Adding a method with a default (as finish_hex already is) stays additive; adding a required one does not.

Traits / Modules

Digest trait
Digest

The streaming-hash interface: new, update, finish_bytes, plus the two sizes HMAC needs — RustCrypto's Digest trait, cut down to what std/crypto actually uses.

Implemented by Sha256, Sha512, Sha1 and Md5, and open to a user type. It exists so hmac can be written once over any hasher: new and the sizes are statics of the implementor, so a where(D <: Digest) function can CONSTRUCT a hasher it was never handed, which a method-only trait could not.

The digest crosses the trait boundary as an ArrayList(u8) — one type for every algorithm — where each implementor's inherent finish() returns a fixed-size Array(u8, N). Prefer the inherent one when the algorithm is known at the call site; it does not allocate.

finish_bytes leaves the hasher in its finalised state rather than consuming it: hash one message per hasher and drop it.

Methods

new : fn() -> Self

A fresh hasher.

Returns: Self

update : fn(self : Self, data : ArrayList(u8)) -> Self

Feed more data.

Parameters

NameTypeNotes
selfSelf
dataArrayList(u8)

Returns: Self

digest_size : fn() -> usize

The digest length in bytes (32/64/20/16).

Returns: usize

block_size : fn() -> usize

The compression block size in bytes (64, or 128 for SHA-512) — what HMAC pads keys to.

Returns: usize

finish_bytes : fn(self : Self) -> ArrayList(u8)

Finalise and return the digest as bytes.

Parameters

NameTypeNotes
selfSelf

Returns: ArrayList(u8)

finish_hex : fn(self : Self) -> String

Finalise and return the lowercase hex digest.

Parameters

NameTypeNotes
selfSelf

Returns: String

Implementors