include "bytedata.s7i";
include "bin32.s7i";
include "bin64.s7i";
include "float.s7i";
include "math.s7i";
const type: digestData16 is array [16] bin32;
const type: digestData64 is array [64] bin32;
const type: digestData80 is array [80] bin32;
const type: bin64digestData80 is array [80] bin64;
const func string: md4 (in var string: message) is func
result
var string: digest is "";
local
const array integer: shiftAmount is [] (
3, 7, 11, 19, 3, 7, 11, 19, 3, 7, 11, 19, 3, 7, 11, 19,
3, 5, 9, 13, 3, 5, 9, 13, 3, 5, 9, 13, 3, 5, 9, 13,
3, 9, 11, 15, 3, 9, 11, 15, 3, 9, 11, 15, 3, 9, 11, 15);
const array integer: idx is [] (
1, 9, 5, 13, 3, 11, 7, 15, 2, 10, 6, 14, 4, 12, 8, 16);
var integer: length is 0;
var integer: wordIndex is 1;
var integer: index is 0;
var digestData16: m is digestData16.value;
var integer: a0 is 16#67452301;
var integer: b0 is 16#efcdab89;
var integer: c0 is 16#98badcfe;
var integer: d0 is 16#10325476;
var bin32: a is bin32(0);
var bin32: b is bin32(0);
var bin32: c is bin32(0);
var bin32: d is bin32(0);
var bin32: f is bin32(0);
var integer: g is 0;
var bin32: temp is bin32(0);
begin
length := length(message);
message &:= '\16#80;';
message &:= "\0;" mult 63 - (length + 8) mod 64;
message &:= bytes(8 * length, UNSIGNED, LE, 8);
while wordIndex <= length(message) do
for index range 1 to 16 do
m[index] := bin32(bytes2Int(message[wordIndex fixLen 4], UNSIGNED, LE));
wordIndex +:= 4;
end for;
a := bin32(a0 mod 16#100000000);
b := bin32(b0 mod 16#100000000);
c := bin32(c0 mod 16#100000000);
d := bin32(d0 mod 16#100000000);
for index range 1 to 48 do
if index <= 16 then
f := d >< (b & (c >< d));
g := index;
elsif index <= 32 then
f := bin32(ord(b & (c | d) | (c & d)) + 16#5a827999);
g := (4 * index + 7) mod 15 + (index mdiv 32) * 15 + 1;
else
f := bin32(ord(b >< c >< d) + 16#6ed9eba1);
g := idx[index - 32];
end if;
temp := d;
d := c;
c := b;
b := rotLeft(bin32((ord(a) + ord(f) + ord(m[g])) mod 16#100000000),
shiftAmount[index]);
a := temp;
end for;
a0 +:= ord(a);
b0 +:= ord(b);
c0 +:= ord(c);
d0 +:= ord(d);
end while;
digest := bytes(a0 mod 16#100000000, UNSIGNED, LE, 4) &
bytes(b0 mod 16#100000000, UNSIGNED, LE, 4) &
bytes(c0 mod 16#100000000, UNSIGNED, LE, 4) &
bytes(d0 mod 16#100000000, UNSIGNED, LE, 4);
end func;
const func array integer: createMd5Table is func
result
var array integer: k is 64 times 0;
local
var integer: index is 0;
begin
for index range 1 to 64 do
k[index] := trunc(abs(sin(flt(index))) * 2.0 ** 32);
end for;
end func;
const func string: md5 (in var string: message) is func
result
var string: digest is "";
local
const array integer: shiftAmount is [] (
7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21);
const array integer: k is createMd5Table;
var integer: length is 0;
var integer: wordIndex is 1;
var integer: index is 0;
var digestData16: m is digestData16.value;
var integer: a0 is 16#67452301;
var integer: b0 is 16#efcdab89;
var integer: c0 is 16#98badcfe;
var integer: d0 is 16#10325476;
var bin32: a is bin32(0);
var bin32: b is bin32(0);
var bin32: c is bin32(0);
var bin32: d is bin32(0);
var bin32: f is bin32(0);
var integer: g is 0;
var bin32: temp is bin32(0);
begin
length := length(message);
message &:= '\16#80;';
message &:= "\0;" mult 63 - (length + 8) mod 64;
message &:= bytes(8 * length, UNSIGNED, LE, 8);
while wordIndex <= length(message) do
for index range 1 to 16 do
m[index] := bin32(bytes2Int(message[wordIndex fixLen 4], UNSIGNED, LE));
wordIndex +:= 4;
end for;
a := bin32(a0 mod 16#100000000);
b := bin32(b0 mod 16#100000000);
c := bin32(c0 mod 16#100000000);
d := bin32(d0 mod 16#100000000);
for index range 1 to 64 do
if index <= 16 then
f := d >< (b & (c >< d));
g := index;
elsif index <= 32 then
f := c >< (d & (b >< c));
g := succ((5 * index - 4) mod 16);
elsif index <= 48 then
f := b >< c >< d;
g := succ((3 * index + 2) mod 16);
else
f := c >< (b | (bin32(16#ffffffff) >< d));
g := succ((7 * pred(index)) mod 16);
end if;
temp := d;
d := c;
c := b;
b := bin32((ord(b) +
ord(rotLeft(bin32((ord(a) + ord(f) + k[index] + ord(m[g])) mod 16#100000000),
shiftAmount[index]))) mod 16#100000000);
a := temp;
end for;
a0 +:= ord(a);
b0 +:= ord(b);
c0 +:= ord(c);
d0 +:= ord(d);
end while;
digest := bytes(a0 mod 16#100000000, UNSIGNED, LE, 4) &
bytes(b0 mod 16#100000000, UNSIGNED, LE, 4) &
bytes(c0 mod 16#100000000, UNSIGNED, LE, 4) &
bytes(d0 mod 16#100000000, UNSIGNED, LE, 4);
end func;
const func string: ripemd160 (in var string: message) is func
result
var string: digest is "";
local
const array integer: k1 is [] (16#00000000, 16#5a827999, 16#6ed9eba1, 16#8f1bbcdc, 16#a953fd4e);
const array integer: k2 is [] (16#50a28be6, 16#5c4dd124, 16#6d703ef3, 16#7a6d76e9, 16#00000000);
const array integer: r1 is [] (
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
8, 5, 14, 2, 11, 7, 16, 4, 13, 1, 10, 6, 3, 15, 12, 9,
4, 11, 15, 5, 10, 16, 9, 2, 3, 8, 1, 7, 14, 12, 6, 13,
2, 10, 12, 11, 1, 9, 13, 5, 14, 4, 8, 16, 15, 6, 7, 3,
5, 1, 6, 10, 8, 13, 3, 11, 15, 2, 4, 9, 12, 7, 16, 14);
const array integer: r2 is [] (
6, 15, 8, 1, 10, 3, 12, 5, 14, 7, 16, 9, 2, 11, 4, 13,
7, 12, 4, 8, 1, 14, 6, 11, 15, 16, 9, 13, 5, 10, 2, 3,
16, 6, 2, 4, 8, 15, 7, 10, 12, 9, 13, 3, 11, 1, 5, 14,
9, 7, 5, 2, 4, 12, 16, 1, 6, 13, 3, 14, 10, 8, 11, 15,
13, 16, 11, 5, 2, 6, 9, 8, 7, 3, 14, 15, 1, 4, 10, 12);
const array integer: s1 is [] (
11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6);
const array integer: s2 is [] (
8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11);
var integer: length is 0;
var integer: wordIndex is 1;
var integer: index is 0;
var array integer: x is 16 times 0;
var integer: h0 is 16#67452301;
var integer: h1 is 16#efcdab89;
var integer: h2 is 16#98badcfe;
var integer: h3 is 16#10325476;
var integer: h4 is 16#c3d2e1f0;
var bin32: a1 is bin32(0);
var bin32: b1 is bin32(0);
var bin32: c1 is bin32(0);
var bin32: d1 is bin32(0);
var bin32: e1 is bin32(0);
var bin32: a2 is bin32(0);
var bin32: b2 is bin32(0);
var bin32: c2 is bin32(0);
var bin32: d2 is bin32(0);
var bin32: e2 is bin32(0);
var integer: t1 is 0;
var integer: t2 is 0;
begin
length := length(message);
message &:= '\16#80;';
message &:= "\0;" mult 63 - (length + 8) mod 64;
message &:= bytes(8 * length, UNSIGNED, LE, 8);
while wordIndex <= length(message) do
for index range 1 to 16 do
x[index] := bytes2Int(message[wordIndex fixLen 4], UNSIGNED, LE);
wordIndex +:= 4;
end for;
a1 := bin32(h0);
b1 := bin32(h1);
c1 := bin32(h2);
d1 := bin32(h3);
e1 := bin32(h4);
a2 := bin32(h0);
b2 := bin32(h1);
c2 := bin32(h2);
d2 := bin32(h3);
e2 := bin32(h4);
for index range 1 to 80 do
case index of
when {1 .. 16}:
t1 := ord(b1 >< c1 >< d1);
t2 := ord(b2 >< (c2 | ~d2)) + k2[1];
when {17 .. 32}:
t1 := ord((b1 & c1) | (~b1 & d1)) + k1[2];
t2 := ord((b2 & d2) | (c2 & ~d2)) + k2[2];
when {33 .. 48}:
t1 := ord((b1 | ~c1) >< d1) + k1[3];
t2 := ord((b2 | ~c2) >< d2) + k2[3];
when {49 .. 64}:
t1 := ord((b1 & d1) | (c1 & ~d1)) + k1[4];
t2 := ord((b2 & c2) | (~b2 & d2)) + k2[4];
when {65 .. 80}:
t1 := ord(b1 >< (c1 | ~d1)) + k1[5];
t2 := ord(b2 >< c2 >< d2);
end case;
t1 +:= ord(a1) + x[r1[index]];
t1 := ord(rotLeft(bin32(t1 mod 16#100000000), s1[index])) + ord(e1);
a1 := e1;
e1 := d1;
d1 := rotLeft(c1, 10);
c1 := b1;
b1 := bin32(t1 mod 16#100000000);
t2 +:= ord(a2) + x[r2[index]];
t2 := ord(rotLeft(bin32(t2 mod 16#100000000), s2[index])) + ord(e2);
a2 := e2;
e2 := d2;
d2 := rotLeft(c2, 10);
c2 := b2;
b2 := bin32(t2 mod 16#100000000);
end for;
t1 := (h1 + ord(c1) + ord(d2)) mod 16#100000000;
h1 := (h2 + ord(d1) + ord(e2)) mod 16#100000000;
h2 := (h3 + ord(e1) + ord(a2)) mod 16#100000000;
h3 := (h4 + ord(a1) + ord(b2)) mod 16#100000000;
h4 := (h0 + ord(b1) + ord(c2)) mod 16#100000000;
h0 := t1;
end while;
digest := bytes(h0, UNSIGNED, LE, 4) &
bytes(h1, UNSIGNED, LE, 4) &
bytes(h2, UNSIGNED, LE, 4) &
bytes(h3, UNSIGNED, LE, 4) &
bytes(h4, UNSIGNED, LE, 4);
end func;
const func string: sha1 (in var string: message) is func
result
var string: digest is "";
local
var integer: length is 0;
var integer: wordIndex is 1;
var integer: index is 0;
var digestData80: w is digestData80.value;
var integer: h0 is 16#67452301;
var integer: h1 is 16#efcdab89;
var integer: h2 is 16#98badcfe;
var integer: h3 is 16#10325476;
var integer: h4 is 16#c3d2e1f0;
var bin32: a is bin32(0);
var bin32: b is bin32(0);
var bin32: c is bin32(0);
var bin32: d is bin32(0);
var bin32: e is bin32(0);
var bin32: f is bin32(0);
var bin32: g is bin32(0);
var integer: temp is 0;
var integer: k is 0;
begin
length := length(message);
message &:= '\16#80;';
message &:= "\0;" mult 63 - (length + 8) mod 64;
message &:= bytes(8 * length, UNSIGNED, BE, 8);
while wordIndex <= length(message) do
for index range 1 to 16 do
w[index] := bin32(bytes2Int(message[wordIndex fixLen 4], UNSIGNED, BE));
wordIndex +:= 4;
end for;
for index range 17 to 80 do
g := w[index-3] >< w[index-8] >< w[index-14] >< w[index-16];
w[index] := rotLeft(g, 1);
end for;
a := bin32(h0 mod 16#100000000);
b := bin32(h1 mod 16#100000000);
c := bin32(h2 mod 16#100000000);
d := bin32(h3 mod 16#100000000);
e := bin32(h4 mod 16#100000000);
for index range 1 to 80 do
if index <= 20 then
f := d >< (b & (c >< d));
k := 16#5a827999;
elsif index <= 40 then
f := b >< c >< d;
k := 16#6ed9eba1;
elsif index <= 60 then
f := (b & c) | (d & (b | c));
k := 16#8f1bbcdc;
else
f := b >< c >< d;
k := 16#ca62c1d6;
end if;
temp := ord(rotLeft(a, 5));
temp +:= ord(f) + ord(e) + k + ord(w[index]);
e := d;
d := c;
c := rotLeft(b, 30);
b := a;
a := bin32(temp mod 16#100000000);
end for;
h0 +:= ord(a);
h1 +:= ord(b);
h2 +:= ord(c);
h3 +:= ord(d);
h4 +:= ord(e);
end while;
digest := bytes(h0 mod 16#100000000, UNSIGNED, BE, 4) &
bytes(h1 mod 16#100000000, UNSIGNED, BE, 4) &
bytes(h2 mod 16#100000000, UNSIGNED, BE, 4) &
bytes(h3 mod 16#100000000, UNSIGNED, BE, 4) &
bytes(h4 mod 16#100000000, UNSIGNED, BE, 4);
end func;
const func string: sha224 (in var string: message) is func
result
var string: digest is "";
local
const array integer: k is [] (
16#428a2f98, 16#71374491, 16#b5c0fbcf, 16#e9b5dba5, 16#3956c25b, 16#59f111f1, 16#923f82a4, 16#ab1c5ed5,
16#d807aa98, 16#12835b01, 16#243185be, 16#550c7dc3, 16#72be5d74, 16#80deb1fe, 16#9bdc06a7, 16#c19bf174,
16#e49b69c1, 16#efbe4786, 16#0fc19dc6, 16#240ca1cc, 16#2de92c6f, 16#4a7484aa, 16#5cb0a9dc, 16#76f988da,
16#983e5152, 16#a831c66d, 16#b00327c8, 16#bf597fc7, 16#c6e00bf3, 16#d5a79147, 16#06ca6351, 16#14292967,
16#27b70a85, 16#2e1b2138, 16#4d2c6dfc, 16#53380d13, 16#650a7354, 16#766a0abb, 16#81c2c92e, 16#92722c85,
16#a2bfe8a1, 16#a81a664b, 16#c24b8b70, 16#c76c51a3, 16#d192e819, 16#d6990624, 16#f40e3585, 16#106aa070,
16#19a4c116, 16#1e376c08, 16#2748774c, 16#34b0bcb5, 16#391c0cb3, 16#4ed8aa4a, 16#5b9cca4f, 16#682e6ff3,
16#748f82ee, 16#78a5636f, 16#84c87814, 16#8cc70208, 16#90befffa, 16#a4506ceb, 16#bef9a3f7, 16#c67178f2);
var integer: length is 0;
var integer: wordIndex is 1;
var integer: index is 0;
var digestData64: w is digestData64.value;
var integer: h0 is 16#c1059ed8;
var integer: h1 is 16#367cd507;
var integer: h2 is 16#3070dd17;
var integer: h3 is 16#f70e5939;
var integer: h4 is 16#ffc00b31;
var integer: h5 is 16#68581511;
var integer: h6 is 16#64f98fa7;
var integer: h7 is 16#befa4fa4;
var bin32: a is bin32(0);
var bin32: b is bin32(0);
var bin32: c is bin32(0);
var bin32: d is bin32(0);
var bin32: e is bin32(0);
var bin32: f is bin32(0);
var bin32: g is bin32(0);
var bin32: h is bin32(0);
var bin32: s0 is bin32(0);
var bin32: s1 is bin32(0);
var integer: temp1 is 0;
var integer: temp2 is 0;
var bin32: ch is bin32(0);
var bin32: maj is bin32(0);
begin
length := length(message);
message &:= '\16#80;';
message &:= "\0;" mult 63 - (length + 8) mod 64;
message &:= bytes(8 * length, UNSIGNED, BE, 8);
while wordIndex <= length(message) do
for index range 1 to 16 do
w[index] := bin32(bytes2Int(message[wordIndex fixLen 4], UNSIGNED, BE));
wordIndex +:= 4;
end for;
for index range 17 to 64 do
w[index] := bin32(ord(w[index-16]) +
ord(rotRight(w[index-15], 7) >< rotRight(w[index-15], 18) >< (w[index-15] >> 3)) +
ord(w[index-7]) +
ord(rotRight(w[index-2], 17) >< rotRight(w[index-2], 19) >< (w[index-2] >> 10))) &
bin32(16#ffffffff);
end for;
a := bin32(h0 mod 16#100000000);
b := bin32(h1 mod 16#100000000);
c := bin32(h2 mod 16#100000000);
d := bin32(h3 mod 16#100000000);
e := bin32(h4 mod 16#100000000);
f := bin32(h5 mod 16#100000000);
g := bin32(h6 mod 16#100000000);
h := bin32(h7 mod 16#100000000);
for index range 1 to 64 do
s1 := rotRight(e, 6) >< rotRight(e, 11) >< rotRight(e, 25);
ch := (e & f) >< ((bin32(16#ffffffff) >< e) & g);
temp1 := ord(h) + ord(s1) + ord(ch) + k[index] + ord(w[index]);
s0 := rotRight(a, 2) >< rotRight(a, 13) >< rotRight(a, 22);
maj := (a & b) >< (a & c) >< (b & c);
temp2 := ord(s0) + ord(maj);
h := g;
g := f;
f := e;
e := bin32((ord(d) + temp1) mod 16#100000000);
d := c;
c := b;
b := a;
a := bin32((temp1 + temp2) mod 16#100000000);
end for;
h0 +:= ord(a);
h1 +:= ord(b);
h2 +:= ord(c);
h3 +:= ord(d);
h4 +:= ord(e);
h5 +:= ord(f);
h6 +:= ord(g);
h7 +:= ord(h);
end while;
digest := bytes(h0 mod 16#100000000, UNSIGNED, BE, 4) &
bytes(h1 mod 16#100000000, UNSIGNED, BE, 4) &
bytes(h2 mod 16#100000000, UNSIGNED, BE, 4) &
bytes(h3 mod 16#100000000, UNSIGNED, BE, 4) &
bytes(h4 mod 16#100000000, UNSIGNED, BE, 4) &
bytes(h5 mod 16#100000000, UNSIGNED, BE, 4) &
bytes(h6 mod 16#100000000, UNSIGNED, BE, 4);
end func;
const func string: sha256 (in var string: message) is func
result
var string: digest is "";
local
const array integer: k is [] (
16#428a2f98, 16#71374491, 16#b5c0fbcf, 16#e9b5dba5, 16#3956c25b, 16#59f111f1, 16#923f82a4, 16#ab1c5ed5,
16#d807aa98, 16#12835b01, 16#243185be, 16#550c7dc3, 16#72be5d74, 16#80deb1fe, 16#9bdc06a7, 16#c19bf174,
16#e49b69c1, 16#efbe4786, 16#0fc19dc6, 16#240ca1cc, 16#2de92c6f, 16#4a7484aa, 16#5cb0a9dc, 16#76f988da,
16#983e5152, 16#a831c66d, 16#b00327c8, 16#bf597fc7, 16#c6e00bf3, 16#d5a79147, 16#06ca6351, 16#14292967,
16#27b70a85, 16#2e1b2138, 16#4d2c6dfc, 16#53380d13, 16#650a7354, 16#766a0abb, 16#81c2c92e, 16#92722c85,
16#a2bfe8a1, 16#a81a664b, 16#c24b8b70, 16#c76c51a3, 16#d192e819, 16#d6990624, 16#f40e3585, 16#106aa070,
16#19a4c116, 16#1e376c08, 16#2748774c, 16#34b0bcb5, 16#391c0cb3, 16#4ed8aa4a, 16#5b9cca4f, 16#682e6ff3,
16#748f82ee, 16#78a5636f, 16#84c87814, 16#8cc70208, 16#90befffa, 16#a4506ceb, 16#bef9a3f7, 16#c67178f2);
var integer: length is 0;
var integer: wordIndex is 1;
var integer: index is 0;
var digestData64: w is digestData64.value;
var integer: h0 is 16#6a09e667;
var integer: h1 is 16#bb67ae85;
var integer: h2 is 16#3c6ef372;
var integer: h3 is 16#a54ff53a;
var integer: h4 is 16#510e527f;
var integer: h5 is 16#9b05688c;
var integer: h6 is 16#1f83d9ab;
var integer: h7 is 16#5be0cd19;
var bin32: a is bin32(0);
var bin32: b is bin32(0);
var bin32: c is bin32(0);
var bin32: d is bin32(0);
var bin32: e is bin32(0);
var bin32: f is bin32(0);
var bin32: g is bin32(0);
var bin32: h is bin32(0);
var bin32: s0 is bin32(0);
var bin32: s1 is bin32(0);
var integer: temp1 is 0;
var integer: temp2 is 0;
var bin32: ch is bin32(0);
var bin32: maj is bin32(0);
begin
length := length(message);
message &:= '\16#80;';
message &:= "\0;" mult 63 - (length + 8) mod 64;
message &:= bytes(8 * length, UNSIGNED, BE, 8);
while wordIndex <= length(message) do
for index range 1 to 16 do
w[index] := bin32(bytes2Int(message[wordIndex fixLen 4], UNSIGNED, BE));
wordIndex +:= 4;
end for;
for index range 17 to 64 do
w[index] := bin32(ord(w[index-16]) +
ord(rotRight(w[index-15], 7) >< rotRight(w[index-15], 18) >< (w[index-15] >> 3)) +
ord(w[index-7]) +
ord(rotRight(w[index-2], 17) >< rotRight(w[index-2], 19) >< (w[index-2] >> 10))) &
bin32(16#ffffffff);
end for;
a := bin32(h0 mod 16#100000000);
b := bin32(h1 mod 16#100000000);
c := bin32(h2 mod 16#100000000);
d := bin32(h3 mod 16#100000000);
e := bin32(h4 mod 16#100000000);
f := bin32(h5 mod 16#100000000);
g := bin32(h6 mod 16#100000000);
h := bin32(h7 mod 16#100000000);
for index range 1 to 64 do
s1 := rotRight(e, 6) >< rotRight(e, 11) >< rotRight(e, 25);
ch := (e & f) >< ((bin32(16#ffffffff) >< e) & g);
temp1 := ord(h) + ord(s1) + ord(ch) + k[index] + ord(w[index]);
s0 := rotRight(a, 2) >< rotRight(a, 13) >< rotRight(a, 22);
maj := (a & b) >< (a & c) >< (b & c);
temp2 := ord(s0) + ord(maj);
h := g;
g := f;
f := e;
e := bin32((ord(d) + temp1) mod 16#100000000);
d := c;
c := b;
b := a;
a := bin32((temp1 + temp2) mod 16#100000000);
end for;
h0 +:= ord(a);
h1 +:= ord(b);
h2 +:= ord(c);
h3 +:= ord(d);
h4 +:= ord(e);
h5 +:= ord(f);
h6 +:= ord(g);
h7 +:= ord(h);
end while;
digest := bytes(h0 mod 16#100000000, UNSIGNED, BE, 4) &
bytes(h1 mod 16#100000000, UNSIGNED, BE, 4) &
bytes(h2 mod 16#100000000, UNSIGNED, BE, 4) &
bytes(h3 mod 16#100000000, UNSIGNED, BE, 4) &
bytes(h4 mod 16#100000000, UNSIGNED, BE, 4) &
bytes(h5 mod 16#100000000, UNSIGNED, BE, 4) &
bytes(h6 mod 16#100000000, UNSIGNED, BE, 4) &
bytes(h7 mod 16#100000000, UNSIGNED, BE, 4);
end func;
const func string: sha384 (in var string: message) is func
result
var string: digest is "";
local
const bigInteger: powTwo64 is 2_**64;
const array bin64: k is [] (
bin64(16#428a2f98d728ae22_), bin64(16#7137449123ef65cd_), bin64(16#b5c0fbcfec4d3b2f_), bin64(16#e9b5dba58189dbbc_),
bin64(16#3956c25bf348b538_), bin64(16#59f111f1b605d019_), bin64(16#923f82a4af194f9b_), bin64(16#ab1c5ed5da6d8118_),
bin64(16#d807aa98a3030242_), bin64(16#12835b0145706fbe_), bin64(16#243185be4ee4b28c_), bin64(16#550c7dc3d5ffb4e2_),
bin64(16#72be5d74f27b896f_), bin64(16#80deb1fe3b1696b1_), bin64(16#9bdc06a725c71235_), bin64(16#c19bf174cf692694_),
bin64(16#e49b69c19ef14ad2_), bin64(16#efbe4786384f25e3_), bin64(16#0fc19dc68b8cd5b5_), bin64(16#240ca1cc77ac9c65_),
bin64(16#2de92c6f592b0275_), bin64(16#4a7484aa6ea6e483_), bin64(16#5cb0a9dcbd41fbd4_), bin64(16#76f988da831153b5_),
bin64(16#983e5152ee66dfab_), bin64(16#a831c66d2db43210_), bin64(16#b00327c898fb213f_), bin64(16#bf597fc7beef0ee4_),
bin64(16#c6e00bf33da88fc2_), bin64(16#d5a79147930aa725_), bin64(16#06ca6351e003826f_), bin64(16#142929670a0e6e70_),
bin64(16#27b70a8546d22ffc_), bin64(16#2e1b21385c26c926_), bin64(16#4d2c6dfc5ac42aed_), bin64(16#53380d139d95b3df_),
bin64(16#650a73548baf63de_), bin64(16#766a0abb3c77b2a8_), bin64(16#81c2c92e47edaee6_), bin64(16#92722c851482353b_),
bin64(16#a2bfe8a14cf10364_), bin64(16#a81a664bbc423001_), bin64(16#c24b8b70d0f89791_), bin64(16#c76c51a30654be30_),
bin64(16#d192e819d6ef5218_), bin64(16#d69906245565a910_), bin64(16#f40e35855771202a_), bin64(16#106aa07032bbd1b8_),
bin64(16#19a4c116b8d2d0c8_), bin64(16#1e376c085141ab53_), bin64(16#2748774cdf8eeb99_), bin64(16#34b0bcb5e19b48a8_),
bin64(16#391c0cb3c5c95a63_), bin64(16#4ed8aa4ae3418acb_), bin64(16#5b9cca4f7763e373_), bin64(16#682e6ff3d6b2b8a3_),
bin64(16#748f82ee5defb2fc_), bin64(16#78a5636f43172f60_), bin64(16#84c87814a1f0ab72_), bin64(16#8cc702081a6439ec_),
bin64(16#90befffa23631e28_), bin64(16#a4506cebde82bde9_), bin64(16#bef9a3f7b2c67915_), bin64(16#c67178f2e372532b_),
bin64(16#ca273eceea26619c_), bin64(16#d186b8c721c0c207_), bin64(16#eada7dd6cde0eb1e_), bin64(16#f57d4f7fee6ed178_),
bin64(16#06f067aa72176fba_), bin64(16#0a637dc5a2c898a6_), bin64(16#113f9804bef90dae_), bin64(16#1b710b35131c471b_),
bin64(16#28db77f523047d84_), bin64(16#32caab7b40c72493_), bin64(16#3c9ebe0a15c9bebc_), bin64(16#431d67c49c100d4c_),
bin64(16#4cc5d4becb3e42b6_), bin64(16#597f299cfc657e2a_), bin64(16#5fcb6fab3ad6faec_), bin64(16#6c44198c4a475817_));
var integer: length is 0;
var integer: chunkIndex is 0;
var integer: index is 0;
var bin64digestData80: w is bin64digestData80.value;
var bin64: h0 is bin64(16#cbbb9d5dc1059ed8_);
var bin64: h1 is bin64(16#629a292a367cd507_);
var bin64: h2 is bin64(16#9159015a3070dd17_);
var bin64: h3 is bin64(16#152fecd8f70e5939_);
var bin64: h4 is bin64(16#67332667ffc00b31_);
var bin64: h5 is bin64(16#8eb44a8768581511_);
var bin64: h6 is bin64(16#db0c2e0d64f98fa7_);
var bin64: h7 is bin64(16#47b5481dbefa4fa4_);
var bin64: a is bin64(0);
var bin64: b is bin64(0);
var bin64: c is bin64(0);
var bin64: d is bin64(0);
var bin64: e is bin64(0);
var bin64: f is bin64(0);
var bin64: g is bin64(0);
var bin64: h is bin64(0);
var bin64: s0 is bin64(0);
var bin64: s1 is bin64(0);
var bin64: temp1 is bin64(0);
var bin64: temp2 is bin64(0);
var bin64: ch is bin64(0);
var bin64: maj is bin64(0);
begin
length := length(message);
message &:= '\16#80;';
message &:= "\0;" mult 127 - (length + 8) mod 128;
message &:= bytes(8 * length, UNSIGNED, BE, 8);
for chunkIndex range 1 to length(message) step 128 do
for index range 0 to 127 do
if ord(message[chunkIndex + index]) > 255 then
raise RANGE_ERROR;
end if;
end for;
for index range 1 to 16 do
w[index] := bin64(message[chunkIndex + 8 * pred(index) fixLen 8], BE);
end for;
for index range 17 to 80 do
w[index] := bin64((big(w[index-16]) +
big(rotRight(w[index-15], 1) ><
rotRight(w[index-15], 8) ><
(w[index-15] >> 7)) +
big(w[index-7]) +
big(rotRight(w[index-2], 19) ><
rotRight(w[index-2], 61) ><
(w[index-2] >> 6))) mod powTwo64);
end for;
a := h0;
b := h1;
c := h2;
d := h3;
e := h4;
f := h5;
g := h6;
h := h7;
for index range 1 to 80 do
s1 := rotRight(e, 14) >< rotRight(e, 18) >< rotRight(e, 41);
ch := (e & f) >< (~e & g);
temp1 := bin64((big(h) + big(s1) + big(ch) + big(k[index]) + big(w[index])) mod powTwo64);
s0 := rotRight(a, 28) >< rotRight(a, 34) >< rotRight(a, 39);
maj := (a & b) >< (a & c) >< (b & c);
temp2 := bin64((big(s0) + big(maj)) mod powTwo64);
h := g;
g := f;
f := e;
e := bin64((big(d) + big(temp1)) mod powTwo64);
d := c;
c := b;
b := a;
a := bin64((big(temp1) + big(temp2)) mod powTwo64);
end for;
h0 := bin64((big(h0) + big(a)) mod powTwo64);
h1 := bin64((big(h1) + big(b)) mod powTwo64);
h2 := bin64((big(h2) + big(c)) mod powTwo64);
h3 := bin64((big(h3) + big(d)) mod powTwo64);
h4 := bin64((big(h4) + big(e)) mod powTwo64);
h5 := bin64((big(h5) + big(f)) mod powTwo64);
h6 := bin64((big(h6) + big(g)) mod powTwo64);
h7 := bin64((big(h7) + big(h)) mod powTwo64);
end for;
digest := bytes(h0, BE, 8) &
bytes(h1, BE, 8) &
bytes(h2, BE, 8) &
bytes(h3, BE, 8) &
bytes(h4, BE, 8) &
bytes(h5, BE, 8);
end func;
const func string: sha512 (in var string: message) is func
result
var string: digest is "";
local
const bigInteger: powTwo64 is 2_**64;
const array bin64: k is [] (
bin64(16#428a2f98d728ae22_), bin64(16#7137449123ef65cd_), bin64(16#b5c0fbcfec4d3b2f_), bin64(16#e9b5dba58189dbbc_),
bin64(16#3956c25bf348b538_), bin64(16#59f111f1b605d019_), bin64(16#923f82a4af194f9b_), bin64(16#ab1c5ed5da6d8118_),
bin64(16#d807aa98a3030242_), bin64(16#12835b0145706fbe_), bin64(16#243185be4ee4b28c_), bin64(16#550c7dc3d5ffb4e2_),
bin64(16#72be5d74f27b896f_), bin64(16#80deb1fe3b1696b1_), bin64(16#9bdc06a725c71235_), bin64(16#c19bf174cf692694_),
bin64(16#e49b69c19ef14ad2_), bin64(16#efbe4786384f25e3_), bin64(16#0fc19dc68b8cd5b5_), bin64(16#240ca1cc77ac9c65_),
bin64(16#2de92c6f592b0275_), bin64(16#4a7484aa6ea6e483_), bin64(16#5cb0a9dcbd41fbd4_), bin64(16#76f988da831153b5_),
bin64(16#983e5152ee66dfab_), bin64(16#a831c66d2db43210_), bin64(16#b00327c898fb213f_), bin64(16#bf597fc7beef0ee4_),
bin64(16#c6e00bf33da88fc2_), bin64(16#d5a79147930aa725_), bin64(16#06ca6351e003826f_), bin64(16#142929670a0e6e70_),
bin64(16#27b70a8546d22ffc_), bin64(16#2e1b21385c26c926_), bin64(16#4d2c6dfc5ac42aed_), bin64(16#53380d139d95b3df_),
bin64(16#650a73548baf63de_), bin64(16#766a0abb3c77b2a8_), bin64(16#81c2c92e47edaee6_), bin64(16#92722c851482353b_),
bin64(16#a2bfe8a14cf10364_), bin64(16#a81a664bbc423001_), bin64(16#c24b8b70d0f89791_), bin64(16#c76c51a30654be30_),
bin64(16#d192e819d6ef5218_), bin64(16#d69906245565a910_), bin64(16#f40e35855771202a_), bin64(16#106aa07032bbd1b8_),
bin64(16#19a4c116b8d2d0c8_), bin64(16#1e376c085141ab53_), bin64(16#2748774cdf8eeb99_), bin64(16#34b0bcb5e19b48a8_),
bin64(16#391c0cb3c5c95a63_), bin64(16#4ed8aa4ae3418acb_), bin64(16#5b9cca4f7763e373_), bin64(16#682e6ff3d6b2b8a3_),
bin64(16#748f82ee5defb2fc_), bin64(16#78a5636f43172f60_), bin64(16#84c87814a1f0ab72_), bin64(16#8cc702081a6439ec_),
bin64(16#90befffa23631e28_), bin64(16#a4506cebde82bde9_), bin64(16#bef9a3f7b2c67915_), bin64(16#c67178f2e372532b_),
bin64(16#ca273eceea26619c_), bin64(16#d186b8c721c0c207_), bin64(16#eada7dd6cde0eb1e_), bin64(16#f57d4f7fee6ed178_),
bin64(16#06f067aa72176fba_), bin64(16#0a637dc5a2c898a6_), bin64(16#113f9804bef90dae_), bin64(16#1b710b35131c471b_),
bin64(16#28db77f523047d84_), bin64(16#32caab7b40c72493_), bin64(16#3c9ebe0a15c9bebc_), bin64(16#431d67c49c100d4c_),
bin64(16#4cc5d4becb3e42b6_), bin64(16#597f299cfc657e2a_), bin64(16#5fcb6fab3ad6faec_), bin64(16#6c44198c4a475817_));
var integer: length is 0;
var integer: chunkIndex is 0;
var integer: index is 0;
var bin64digestData80: w is bin64digestData80.value;
var bin64: h0 is bin64(16#6a09e667f3bcc908_);
var bin64: h1 is bin64(16#bb67ae8584caa73b_);
var bin64: h2 is bin64(16#3c6ef372fe94f82b_);
var bin64: h3 is bin64(16#a54ff53a5f1d36f1_);
var bin64: h4 is bin64(16#510e527fade682d1_);
var bin64: h5 is bin64(16#9b05688c2b3e6c1f_);
var bin64: h6 is bin64(16#1f83d9abfb41bd6b_);
var bin64: h7 is bin64(16#5be0cd19137e2179_);
var bin64: a is bin64(0);
var bin64: b is bin64(0);
var bin64: c is bin64(0);
var bin64: d is bin64(0);
var bin64: e is bin64(0);
var bin64: f is bin64(0);
var bin64: g is bin64(0);
var bin64: h is bin64(0);
var bin64: s0 is bin64(0);
var bin64: s1 is bin64(0);
var bin64: temp1 is bin64(0);
var bin64: temp2 is bin64(0);
var bin64: ch is bin64(0);
var bin64: maj is bin64(0);
begin
length := length(message);
message &:= '\16#80;';
message &:= "\0;" mult 127 - (length + 8) mod 128;
message &:= bytes(8 * length, UNSIGNED, BE, 8);
for chunkIndex range 1 to length(message) step 128 do
for index range 0 to 127 do
if ord(message[chunkIndex + index]) > 255 then
raise RANGE_ERROR;
end if;
end for;
for index range 1 to 16 do
w[index] := bin64(message[chunkIndex + 8 * pred(index) fixLen 8], BE);
end for;
for index range 17 to 80 do
w[index] := bin64((big(w[index-16]) +
big(rotRight(w[index-15], 1) ><
rotRight(w[index-15], 8) ><
(w[index-15] >> 7)) +
big(w[index-7]) +
big(rotRight(w[index-2], 19) ><
rotRight(w[index-2], 61) ><
(w[index-2] >> 6))) mod powTwo64);
end for;
a := h0;
b := h1;
c := h2;
d := h3;
e := h4;
f := h5;
g := h6;
h := h7;
for index range 1 to 80 do
s1 := rotRight(e, 14) >< rotRight(e, 18) >< rotRight(e, 41);
ch := (e & f) >< (~e & g);
temp1 := bin64((big(h) + big(s1) + big(ch) + big(k[index]) + big(w[index])) mod powTwo64);
s0 := rotRight(a, 28) >< rotRight(a, 34) >< rotRight(a, 39);
maj := (a & b) >< (a & c) >< (b & c);
temp2 := bin64((big(s0) + big(maj)) mod powTwo64);
h := g;
g := f;
f := e;
e := bin64((big(d) + big(temp1)) mod powTwo64);
d := c;
c := b;
b := a;
a := bin64((big(temp1) + big(temp2)) mod powTwo64);
end for;
h0 := bin64((big(h0) + big(a)) mod powTwo64);
h1 := bin64((big(h1) + big(b)) mod powTwo64);
h2 := bin64((big(h2) + big(c)) mod powTwo64);
h3 := bin64((big(h3) + big(d)) mod powTwo64);
h4 := bin64((big(h4) + big(e)) mod powTwo64);
h5 := bin64((big(h5) + big(f)) mod powTwo64);
h6 := bin64((big(h6) + big(g)) mod powTwo64);
h7 := bin64((big(h7) + big(h)) mod powTwo64);
end for;
digest := bytes(h0, BE, 8) &
bytes(h1, BE, 8) &
bytes(h2, BE, 8) &
bytes(h3, BE, 8) &
bytes(h4, BE, 8) &
bytes(h5, BE, 8) &
bytes(h6, BE, 8) &
bytes(h7, BE, 8);
end func;
const type: digestAlgorithm is new enum
NO_DIGEST, MD4, MD5, RIPEMD160, SHA1, SHA224, SHA256, SHA384, SHA512
end enum;
const func string: msgDigest (in digestAlgorithm: digestAlg, in string: message) is DYNAMIC;
const func string: msgDigest (NO_DIGEST, in string: message) is return "";
const func string: msgDigest (MD4, in string: message) is return md4(message);
const func string: msgDigest (MD5, in string: message) is return md5(message);
const func string: msgDigest (RIPEMD160, in string: message) is return ripemd160(message);
const func string: msgDigest (SHA1, in string: message) is return sha1(message);
const func string: msgDigest (SHA224, in string: message) is return sha224(message);
const func string: msgDigest (SHA256, in string: message) is return sha256(message);
const func string: msgDigest (SHA384, in string: message) is return sha384(message);
const func string: msgDigest (SHA512, in string: message) is return sha512(message);
const func integer: blockSize (in digestAlgorithm: digestAlg) is DYNAMIC;
const func integer: blockSize (NO_DIGEST) is 0;
const func integer: blockSize (MD4) is 64;
const func integer: blockSize (MD5) is 64;
const func integer: blockSize (RIPEMD160) is 64;
const func integer: blockSize (SHA1) is 64;
const func integer: blockSize (SHA224) is 64;
const func integer: blockSize (SHA256) is 64;
const func integer: blockSize (SHA384) is 128;
const func integer: blockSize (SHA512) is 128;
const func integer: digestSize (in digestAlgorithm: digestAlg) is DYNAMIC;
const func integer: digestSize (NO_DIGEST) is 0;
const func integer: digestSize (MD4) is 16;
const func integer: digestSize (MD5) is 16;
const func integer: digestSize (RIPEMD160) is 20;
const func integer: digestSize (SHA1) is 20;
const func integer: digestSize (SHA224) is 28;
const func integer: digestSize (SHA256) is 32;
const func integer: digestSize (SHA384) is 48;
const func integer: digestSize (SHA512) is 64;