SHA-256: Difference between revisions

5,380 bytes added ,  8 years ago
(Added DWScript version)
Line 1,475:
 
(bye)</lang>
 
=={{header|Phix}}==
Using a pre-built dll (source and binary included in the standard distro)
<lang Phix>constant lib = open_dll("SHA.DLL")
constant SHA_HashBlock = define_c_proc(lib,"SHA_HashBlock",{C_PTR,C_PTR,C_INT})
 
function sha256(string s)
atom mem = allocate(32)
sequence res
c_proc(SHA_HashBlock,{s,mem,length(s)})
res = peek4u({mem,8})
free(mem)
for i=1 to length(res) do
res[i] = sprintf("%08x",res[i])
end for
return join(res)
end function
 
?sha256("Rosetta code")</lang>
{{out}}
<pre>
"764FAF5C 61AC315F 1497F9DF A5427139 65B785E5 CC2F707D 6468D7D1 124CDFCF"
</pre>
The following is, I feel, more in the spirit of this site (same output)
<lang Phix>--
-- 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} = {g,f,e,uint32(d+temp1),c,b,a,uint32(temp1+temp2)} -- (works fine)
{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
 
string res = sha256("Rosetta code")
?res</lang>
 
=={{header|PHP}}==
7,830

edits