Module crypto/sha256

crypto/sha256
Stability: unstable — the algorithm is fixed by FIPS 180-4 and the vectors are tested (`tests/crypto/sha256.test.yo`, plus the streaming-equals- one-shot check in `tests/crypto/digest.test.yo`), so what is unstable is the SHAPE, not the answer. Every digest is reachable two ways — the inherent `finish() -> Array(u8, 32)` and the `Digest` trait's `finish_bytes() -> ArrayList(u8)` — and which is canonical is not settled; there is no `reset`; and `finish` neither consumes nor resets the hasher, so a second call silently returns a digest of the padded state. Freezing follows those decisions in `std/crypto/digest`. A `Sha224` sibling (the same core with a different IV and a truncated output) would be additive. — stable modules only change additively; this one may still change.

SHA-256 hash function (FIPS 180-4), pure Yo implementation.

Example

{ sha256_hex } :: import("std/crypto/sha256");

digest := sha256_hex(data);  // "2cf24dba..."

Stability

unstable — the algorithm is fixed by FIPS 180-4 and the vectors are tested (tests/crypto/sha256.test.yo, plus the streaming-equals- one-shot check in tests/crypto/digest.test.yo), so what is unstable is the SHAPE, not the answer. Every digest is reachable two ways — the inherent finish() -> Array(u8, 32) and the Digest trait's finish_bytes() -> ArrayList(u8) — and which is canonical is not settled; there is no reset; and finish neither consumes nor resets the hasher, so a second call silently returns a digest of the padded state. Freezing follows those decisions in std/crypto/digest. A Sha224 sibling (the same core with a different IV and a truncated output) would be additive.

Types

Sha256 object
Sha256

A streaming SHA-256 hasher: 32-byte digest, 64-byte block, big-endian throughout — RustCrypto's Sha256.

Feed it with update (any number of times, any chunk sizes) and finish with finish. Splitting the input differently cannot change the digest; the hasher buffers a partial block internally.

A ref type, so a copy of the value is the same hasher — passing it around does not fork the state. Use sha256 / sha256_hex when the whole message is already in hand.

Fields

NameTypeDescription
_hArray(u32, 8)
_bufArray(u8, 64)
_buflenusize
_totalu64

Trait Implementations

impl(Sha256, ...)
new : (Sha256) fn() -> Sha256

A hasher seeded with the FIPS 180-4 initial state, ready for update.

Returns: Sha256

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

Absorb data into the hash and return the same hasher, so calls chain: Sha256.new().update(a).update(b).finish().

O(len(data)). The return value is the receiver, not a copy — the hasher is mutated in place either way, so ignoring the result is equally correct.

Parameters

NameTypeNotes
selfSha256
dataArrayList(u8)

Returns: Sha256

finish : (Sha256) fn(self : Sha256) -> Array(u8, 32)

Append the FIPS padding and the message-length field, fold the last block in, and return the 32-byte digest.

Single use. The padding is written into the hasher's own buffer and folded into its state, so calling finish twice hashes that padding as if it were more message and returns a digest of nothing you fed it. RustCrypto's finalize(self) makes that a compile error; here it is a rule — one hasher, one message.

Parameters

NameTypeNotes
selfSha256

Returns: Array(u8, 32)

impl(Sha256, Digest(...))
new : (Sha256) fn() -> Sha256

A hasher seeded with the FIPS 180-4 initial state, ready for update.

Returns: Sha256

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

Absorb data into the hash and return the same hasher, so calls chain: Sha256.new().update(a).update(b).finish().

O(len(data)). The return value is the receiver, not a copy — the hasher is mutated in place either way, so ignoring the result is equally correct.

Parameters

NameTypeNotes
selfSha256
dataArrayList(u8)

Returns: Sha256

digest_size : (Sha256) fn() -> usize

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

Returns: usize

block_size : (Sha256) fn() -> usize

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

Returns: usize

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

Finalise and return the digest as bytes.

Parameters

NameTypeNotes
selfSha256

Returns: ArrayList(u8)

Methods
finish_hex : (Sha256) fn(self : Sha256) -> String

Finalise and return the lowercase hex digest.

Parameters

NameTypeNotes
selfSha256

Returns: String

Functions

sha256 function
fn(data : ArrayList(u8)) -> Array(u8, usize(32))

SHA-256 of data in one call — the 32-byte digest.

Exactly Sha256.new().update(data).finish(), so use it whenever the whole message is in memory; reach for the Sha256 type only to hash in pieces.

Parameters

NameTypeNotes
dataArrayList(u8)

Returns: Array(u8, usize(32))

sha256_hex function
fn(data : ArrayList(u8)) -> String

SHA-256 of data as 64 lowercase hex characters — the spelling checksums are usually published in.

Convenience over sha256 + hex_encode; it allocates the String. Compare hex digests with care: use constant_time_eq (std/crypto/hmac) when the comparison is a security decision.

Parameters

NameTypeNotes
dataArrayList(u8)

Returns: String