This is the source
code
being analyzed. The block size is 64 bytes and the number of rounds is 64.
These are not explicitly defined but used inline.
1. Initialization
Line
19
defines the 64 round constants of size 32-bits each.
private let K : [Nat32] = [
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
...
];
Line
38
initialized the 8 initial hash values of 32-bits each.
private let S : [Nat32] = [
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
];
2. Processing
The processing phase is a collaboration between the functions
write
and
block.
The block at Line
71
checks if there is already buffered data and appends incoming bytes to it
at most until it fills BLOCK_SIZE.
let n = Nat.min(p.size(), 64 - nx);
for (i in Iter.range(0, n - 1)) {
x[nx + i] := p[i];
};
If the buffer size reaches BLOCK_SIZE send to block where the hash values
get updated:
if (nx == 64) {
let buf = Array.freeze<Nat8>(x);
block(buf);
nx := 0;
};
If the remaining data has enough bytes to fill a BLOCK_SIZE, it will be
processed by block up to its last chunk if it's not yet of size BLOCK_SIZE.
3. Sum
The function
sum
handles padding and outputting the final hash.