In practice (i.e. when actually implementing the function), you do not really calculate $k$. Things rather work like this: you have a 64-byte buffer. You process incoming data through that buffer; when it is full, you apply the compression function, which mutates the internal state (five 32-bit words for SHA-1, eight for SHA-256), and begin again at offset 0 in the buffer. In other words, you keep an internal pointer (or index) to the first free byte in the buffer. With C notation, let's call buf
the buffer and ptr
the index. ptr
always has a value between 0 (buffer is empty) and 63 (buffer is almost full, only needs one extra byte)(Note: I am assuming that you are processing byte-oriented data, i.e. you never have individual bits, only bytes -- I have yet to encounter a practical situation where this is not true).
When it comes to finishing the computation, you have, at that point, between 0 and 63 bytes of unprocessed data in your buffer. You add the extra "1" bit as an extra byte of value 0x80, which in C is:
buf[ptr ++] = 0x80;
Then you have to add "enough zeros, then the length over 64 bits", so the code should look like this:
if (ptr <= 56) {
memset(buf + ptr, 0, 56 - ptr);
} else {
memset(buf + ptr, 0, 64 - ptr);
call_compression_function();
memset(buf, 0, 56);
}
encode_length(buf + 56);
call_compression_function();
where encode_length()
writes out the 64-bit bit length of the input message at the specified address (big-endian convention), and call_compression_function()
invokes the compression function over the data in buf[]
.
So the value of $k$ is never really computed; it is the sum of the third arguments to the calls to memset()
(+7 for the seven zeros implied in the 0x80 extra byte).
Self-promotion: you can see how such code looks like, in C and Java, in the opensource library sphlib.
k
should be the smallest, non-negative solution. – Stijn Aug 31 '11 at 17:05k = 447 - l + 512 * floor((l + 64) / 512)
forl=24,448
? – Nov 21 '11 at 16:36k
. – Stijn Nov 22 '11 at 00:34