Applying the recurrence 48 times fills out the complete 64-word message schedule for a block. Today you wrap it in one function and pin the last word for the "abc" block.
Expand a 64-byte block into the full 64-word message schedule W0 through W63.
Growing the schedule is just applying last lesson’s recurrence in a loop from
t = 16 to t = 63, each step reading four words that already exist. Because the
words are computed strictly in order, every reference W[t-2], W[t-7], W[t-15], W[t-16] points at a word filled earlier in the same loop - the recurrence never
looks ahead. Sixteen seed words in, sixty-four words out.
This is the per-block input the compression function will consume: one schedule
word per round. Pin the tail, W[63] = 0x12b1edeb, because it depends on the
entire chain of 48 recurrence steps - if any small sigma amount, index offset, or
modular add is off anywhere along the way, this last word will not match. Getting
W[63] right for the “abc” block is strong evidence the whole schedule is
correct before you build the rounds that rely on it.
func ExpandSchedule(block []byte) [64]uint32 {var w [64]uint32first := MessageWords(block)copy(w[:16], first[:])for t := 16; t < 64; t++ {// w[t] = SmallSigma1(w[t-2]) + w[t-7] + SmallSigma0(w[t-15]) + w[t-16]// (fill in, all mod 2^32)}return w}