std/digest/lib
std/digest/src/lib.trb
Message digests: Sha256 and Sha512 (FIPS 180-4), Sha1 (FIPS 180-4 / RFC 3174) and Md5 (RFC 1321, legacy -
see its own doc comment), and the Digest all four answer. SHA-256 is what the package manager pins a package by
(docs/design/RELEASE.md section 7.2) and what a download is checked against; SHA-512 is what Ed25519 hashes with
(std/signature).
Hmac (RFC 2104) is written once, over the Hasher trait every one of the four implements, and Hmac.pbkdf2 is
PBKDF2 (RFC 8018) over it: SCRAM's password hash, and everything else that stretches a password or a key.
Ordinary TorbScript with no native. SHA-256, SHA-1 and MD5 work over Int, every word kept below 2^32 by a mask, so
nothing overflows; SHA-512 over UInt64 and its wrapping sum. The same bytes give the same digest in both back
ends.
Examples
print Sha256.of("abc".bytes()).hex()
// prints ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
var hasher = Sha256()
hasher.add "ab".bytes()
hasher.add "c".bytes()
print hasher.finished().hex()
// prints ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
const expected = Sha256.of "abc".bytes()
const received = Sha256.of "abc".bytes()
print expected.equalsConstantTime(received)
// prints true
type Digest
type Digest with Show
What a hash function answers: its bytes, most significant first, shown as lowercase hexadecimal.
field bytes
bytes: Bytes
fn hex
fn hex(): String
Two lowercase hexadecimal digits per byte: the spelling of sha256sum and of a lock file.
fn show
fn show(): String
The lowercase hexadecimal spelling, the same as Digest.hex.
fn equalsConstantTime
fn equalsConstantTime(other: Digest): Bool
Whether other has the same bytes, answered without the running time depending on where they first differ: every
byte pair is read and the differences are combined by XOR and OR, with no early exit. Use it, not ==, to check a
Hmac result against a MAC, a token or a digest that came from outside. Digests of different lengths are not equal;
the lengths themselves are not secret and are compared first.
The source has no data-dependent branch or early exit; a compiler or a CPU may still introduce a timing effect, and nothing here promises otherwise.
fn constantTimeEqual
fn constantTimeEqual(a: Bytes, b: Bytes): Bool
Digest.equalsConstantTime over two plain byte sequences: a thin wrapper for a caller that holds Bytes, not a
Digest. Prefer the method where a Digest is at hand.
trait Hasher
trait Hasher
A hash function fed in pieces, the shape Sha256, Sha512, Sha1 and Md5 share: a fresh value starts empty,
Hasher.add feeds the next bytes, and Hasher.finished answers the Digest of everything fed so far without
changing the hasher itself; Hasher.of is the one-call shortcut. Hasher.blockSize and Hasher.digestLength are
what Hmac needs to pad a key and to size a PBKDF2 block, and never anything a caller reads for its own sake.
A hash function's own equality-hashing (with Hash, std/core) is a different trait entirely - this one is named
after the cryptographic sense of the word, the one HMAC and PBKDF2 are generic over.
fn empty
static fn empty(): Self
A hasher with nothing fed yet, equivalent to Self(): what a generic caller starts from without naming the type.
fn of
static fn of(bytes: Bytes): Digest
The digest of bytes in one call.
fn add
var fn add(bytes: Bytes)
Feeds the next bytes.
fn finished
fn finished(): Digest
The digest of everything added so far. The hasher itself is unchanged and may be fed more.
fn blockSize
static fn blockSize(): Int
The block size HMAC pads a key to and splits a key longer than it by hashing: 64 for every hash here but SHA-512.
fn digestLength
static fn digestLength(): Int
How many bytes a digest of this hash is.
type Sha256
type Sha256 with Hasher
SHA-256, fed in pieces: Sha256.add takes the next bytes and Sha256.finished answers the digest of everything added
so far without changing the hasher, so a hasher can be read, fed more, and read again.
fn empty
static fn empty(): Self
A hasher with nothing fed yet, the same as Self().
fn of
static fn of(bytes: Bytes): Digest
The digest of bytes in one call.
fn blockSize
static fn blockSize(): Int
64: SHA-256 works in blocks of sixteen 32-bit words.
fn digestLength
static fn digestLength(): Int
32: a SHA-256 digest is 256 bits.
fn add
var fn add(bytes: Bytes)
Feeds the next bytes.
fn finished
fn finished(): Digest
The digest of everything added so far. The hasher itself is unchanged and may be fed more.