40 ≤ i ≤ 59 f = (b and c) xor (b and d) xor (c and d) k = 0x8F1BBCDC else if 60 ≤ i ≤ 79 f = b xor c xor d k = 0xCA62C1D6 temp = (a leftrotate 5) + f + e + k + w[i] e = d d = c c = b leftrotate 30 b = a a = temp Add this chunk's hash to result so far: h0 = h0 + a h1 = h1 + b h2 = h2 + c h3 = h3 + d h4 = h4 + e Produce the final hash value (big-endian) as a 160-bit number: hh = (h0 leftshift 128) or (h1 leftshift 96) or (h2 leftshift 64) or (h3 leftshift 32) or h4 The number hh is the message digest, which can be written in hexadecimal (base 16). The chosen constant values used in the algorithm were assumed to be nothing up my sleeve numbers: The four round constants k are 230 times the square roots of 2, 3, 5 and 10. However they were incorrectly rounded to the nearest integer instead of being rounded to the nearest odd integer, with equilibrated proportions of zero and one bits. As well, choosing the square root of 10 (which is not a prime) made it a common factor for the two other chosen square roots of primes 2 and 5, with possibly usable arithmetic properties across successive rounds, reducing the strength of the algorithm against finding collisions on some bits. The first four starting values for h0 through h3 are the same with the MD5 algorithm, and the fifth (for h4) is similar. However they were not properly verified for being resistant against inversion of the few first rounds to infer possible collisions on some bits, usable by multiblock differential attacks. Instead of the formulation from the original FIPS PUB 180-1 shown, the following equivalent expressions may be used to compute f in the main loop above: Bitwise choice between c and d, controlled by b. (0 ≤ i ≤ 19): f = d xor (b and (c xor d)) (alternative 1) (0 ≤ i ≤ 19): f = (b and c) or ((not b) and d) (alternative 2) (0 ≤ i ≤ 19): f = (b and c) xor ((not b) and d) (alternative 3) (0 ≤ i ≤ 19): f = vec_sel(d, c,