-- -- demo\rosetta\sha-256.exw -- ======================== -- -- fairly faithful rendition of https://en.wikipedia.org/wiki/SHA-2 -- with slightly improved names (eg s0 -> sigma0) from elsewhere. -- See also sha-256asm.exw for a faster inline asm version, and -- sha-256dll.exw is much shorter as it uses a pre-built dll. --Initial array of round constants --(first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311): constant k = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2} function pad64(integer v) -- round v up to multiple of 64 return floor((v+63)/64)*64 end function constant m4 = allocate(4) -- scratch area, for uint32 function uint32(atom v) -- -- (note: I have experimented to call this as few times as possible. -- It wouldn't hurt to perform this on every maths op, but a -- few leading bits in a few work fields don't matter much.) -- poke4(m4,v) return peek4u(m4) end function function sq_uint32(sequence s) -- apply unit32 to all elements of s for i=1 to length(s) do s[i] = uint32(s[i]) end for return s end function function dword(string msg, integer i) -- get dword as big-endian return msg[i]*#1000000+msg[i+1]*#10000+msg[i+2]*#100+msg[i+3] end function function shr(atom v, integer bits) return floor(v/power(2,bits)) end function function ror(atom v, integer bits) return or_bits(shr(v,bits),v*power(2,32-bits)) end function function sha256(string msg) -- main function atom s0,s1,a,b,c,d,e,f,g,h,ch,temp1,maj,temp2,x sequence w = repeat(0,64) sequence res integer len = length(msg)+1 --Initial hash values --(first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19) atom h0 = 0x6a09e667, h1 = 0xbb67ae85, h2 = 0x3c6ef372, h3 = 0xa54ff53a, h4 = 0x510e527f, h5 = 0x9b05688c, h6 = 0x1f83d9ab, h7 = 0x5be0cd19 -- add the '1' bit and space for size in bits, padded to multiple of 64 msg &= #80&repeat('\0',pad64(len+8)-len) len = (len-1)*8 for i=length(msg) to 1 by -1 do msg[i] = and_bits(len,#FF) len = floor(len/#100) if len=0 then exit end if end for -- Process the message in successive 512-bit (64 byte) chunks for chunk=1 to length(msg) by 64 do for i=1 to 16 do w[i] = dword(msg,chunk+(i-1)*4) end for -- Extend the first 16 words into the remaining 48 words w[17..64] of the message schedule array for i=17 to 64 do x = w[i-15]; s0 = xor_bits(xor_bits(ror(x, 7),ror(x,18)),shr(x, 3)) x = w[i-2]; s1 = xor_bits(xor_bits(ror(x,17),ror(x,19)),shr(x,10)) w[i] = uint32(w[i-16]+s0+w[i-7]+s1) end for -- Initialize working variables to current hash value {a,b,c,d,e,f,g,h} = {h0,h1,h2,h3,h4,h5,h6,h7} -- Compression function main loop for i=1 to 64 do s1 = xor_bits(xor_bits(ror(e,6),ror(e,11)),ror(e,25)) ch = xor_bits(and_bits(e,f),and_bits(not_bits(e),g)) temp1 = h+s1+ch+k[i]+w[i] s0 = xor_bits(xor_bits(ror(a,2),ror(a,13)),ror(a,22)) maj = xor_bits(xor_bits(and_bits(a,b),and_bits(a,c)),and_bits(b,c)) temp2 = s0+maj {h,g,f,e,d,c,b,a} = sq_uint32({g,f,e,d+temp1,c,b,a,temp1+temp2}) end for -- Add the compressed chunk to the current hash value {h0,h1,h2,h3,h4,h5,h6,h7} = sq_add({h0,h1,h2,h3,h4,h5,h6,h7},{a,b,c,d,e,f,g,h}) end for -- Produce the final hash value (big-endian) res = sq_uint32({h0, h1, h2, h3, h4, h5, h6, h7}) -- (or do sq_unit32 on the sq_add above) for i=1 to length(res) do res[i] = sprintf("%08x",res[i]) end for return join(res) end function ?sha256("Rosetta code")