2
$\begingroup$

So, earlier, I posed a question regarding getting a user implemented SHA-1 hash function to work correctly. Well, I fixed the problems, cleaned it up a little bit, but now I have the problem for when the string's length is greater then 512 bits, the hash function is not operating correctly. Below is the code: The issue appears to be when the 512>Length[message]>448. Any suggestions?

 ef[t_, b_, c_, d_] := 
  Which[0 <= t <= 19, (BitOr[BitAnd[b, c], BitAnd[BitNot[b], d]]), 
   20 <= t <= 39, BitXor[b, c, d], 
   40 <= t <= 59, (BitOr[BitAnd[b, c], BitAnd[b, d], BitAnd[c, d]]), 
   60 <= t <= 79, BitXor[b, c, d]];

k[t_] := Which[0 <= t <= 19, FromDigits["5a827999", 16], 
   20 <= t <= 39, FromDigits["6ed9eba1", 16], 40 <= t <= 59, 
   FromDigits["8f1bbcdc", 16], 60 <= t <= 79, 
   FromDigits["ca62c1d6", 16]];

CirclePlus[x__] := Mod[Plus[x], 2^32];

sha1[msg_] := 
 Module[{pp, eta, temp, al, v, test, fs, jj, i, output, r, l, L, w, x, a, b,
  c, d, e, h1, h2, h3, h4, h5, \[Beta]},
  \[Beta] = Characters[msg];
  r = Flatten[IntegerDigits[ToCharacterCode[#], 2, 8] & /@ \[Beta]];
  l = Length[r];
  L = Floor[l/512] + 1;
  l = Mod[l, 512];
  Echo[L];
  AppendTo[r, Join[{1}, Table[0, {512 - (l + 65)}]]];
  AppendTo[r, IntegerDigits[l, 2, 64]];
  r = Flatten[r];
  Echo[Length[r]];
  w = Table[r[[512 i + 1 ;; 512 (i + 1)]], {i, 0, L - 1}];
  Table[Echo[Length[w[[u]]]], {u, 1, L}];
  {h1, h2, h3, h4, h5} = {FromDigits["67452301", 16], 
    FromDigits["efcdab89", 16], FromDigits["98badcfe", 16], 
    FromDigits["10325476", 16], FromDigits["c3d2e1f0", 16]};
  For[i = 1, i <= L, i++,

   x = Table[
     FromDigits[w[[i]][[32*j + 1 ;; 32*(j + 1)]], 2], {j, 0, 15}];

   For[fs = 17, fs <= 80, fs++,
    temp = 
     FromDigits[
      RotateLeft[
       IntegerDigits[
        BitXor[x[[fs - 3]], x[[fs - 8]], x[[fs - 14]], x[[fs - 16]]], 
        2, 32], 1], 2];
    AppendTo[x, temp];
    ];

   {a, b, c, d, e} = {h1, h2, h3, h4, h5};

   For[jj = 1, jj <= 80, jj++,
    al = FromDigits[RotateLeft[IntegerDigits[a, 2, 32], 5], 2];
    pp = ef[jj - 1, b, c, d];
    test = 
     al\[CirclePlus]pp\[CirclePlus]e\[CirclePlus]x[[
       jj]]\[CirclePlus]k[jj - 1];
    e = d;
    d = c;
    c = FromDigits[RotateLeft[IntegerDigits[b, 2, 32], 30], 2];
    b = a;
    a = test;
    ];

   {h1, h2, h3, h4, h5} = {h1\[CirclePlus]a, h2\[CirclePlus]b, 
     h3\[CirclePlus]c, h4\[CirclePlus]d, h5\[CirclePlus]e};
   ];
  output = BitOr[2^128*h1, 2^96*h2, 2^64*h3, 2^32*h4, h5];
  {output, BaseForm[output, 16]}
  ]

Some case tests:

 f = "Signed by Administrator on April 19th 2019";
 r = sha1[f][[1]];
 t = Hash[f, "SHA"];
 r - t

0

And, with more than 512 bits,

f = "Signed by Administrator on April 19th 2019, testing a string greater than 512 bits"

r = sha1[f][[1]];
t = Hash[f, "SHA"];
r - t

9b4cc069c8b83cb8635781d61791a4d0b6397631

Lets try another random sentence:

f = "I really wish I could understand the problem."
r = sha1[f][[1]]
t = Hash[f, "SHA"]
r - t

0

f = "I really wish I could understand the problem. This is extremely
irritating, I feel as though I've implemented this correctly!!!"
r = sha1[f][[1]]
t = Hash[f, "SHA"]
r - t

41450d1c29b13d9446ab95ef81b516f9c5fe2c85

I'd LOVE any ideas on where I've gone wrong.

$\endgroup$
3
$\begingroup$

The following changes to the beginning of the code (all before the first For[] loop) fixes the code for any amount of bits/ bytes.

ef[t_, b_, c_, d_] := 
  Which[0 <= t <= 19, (BitOr[BitAnd[b, c], BitAnd[BitNot[b], d]]), 
   20 <= t <= 39, BitXor[b, c, d], 
   40 <= t <= 59, (BitOr[BitAnd[b, c], BitAnd[b, d], BitAnd[c, d]]), 
   60 <= t <= 79, BitXor[b, c, d]];

k[t_] := Which[0 <= t <= 19, FromDigits["5a827999", 16], 
   20 <= t <= 39, FromDigits["6ed9eba1", 16], 40 <= t <= 59, 
   FromDigits["8f1bbcdc", 16], 60 <= t <= 79, 
   FromDigits["ca62c1d6", 16]];

CirclePlus[x__] := Mod[Plus[x], 2^32];

sha1[msg_] := 
 Module[{pp, eta, temp, al, v, fs, jj, ll, i, output, r, l, L, w, x, 
   a, b, c, d, e, h1, h2, h3, h4, h5, \[Eta], \[Beta]}, \[Beta] = 
   Characters[msg]; 
  r = Flatten[IntegerDigits[ToCharacterCode[#], 2, 8] & /@ \[Beta]]; 
  l = Length[r]; Echo[l];
  lj = Mod[l + 65, 512]; L = Floor[(l + 65)/512] + 1; 
  AppendTo[r, Join[{1}, Table[0, {512 - (lj)}]]]; 
  AppendTo[r, IntegerDigits[l, 2, 64]]; r = Flatten[r]; 
  Echo[Length[r]];
  Echo[L]; w = Table[r[[512 i + 1 ;; 512 (i + 1)]], {i, 0, L - 1}]; 
  Table[Echo[Length[w[[u]]]], {u, 1, L}]; {h1, h2, h3, h4, 
    h5} = {FromDigits["67452301", 16], FromDigits["efcdab89", 16], 
    FromDigits["98badcfe", 16], FromDigits["10325476", 16], 
    FromDigits["c3d2e1f0", 16]}; 
  For[i = 1, i <= L, i++, 
   x = Table[
     FromDigits[w[[i]][[32*j + 1 ;; 32*(j + 1)]], 2], {j, 0, 15}]; 
   For[fs = 17, fs <= 80, fs++, 
    temp = FromDigits[
      RotateLeft[
       IntegerDigits[
        BitXor[x[[fs - 3]], x[[fs - 8]], x[[fs - 14]], x[[fs - 16]]], 
        2, 32], 1], 2];
    AppendTo[x, temp];]; {a, b, c, d, e} = {h1, h2, h3, h4, h5}; 
   For[jj = 1, jj <= 80, jj++, 
    al = FromDigits[RotateLeft[IntegerDigits[a, 2, 32], 5], 2];
    pp = ef[jj - 1, b, c, d];
    temp = 
     al\[CirclePlus]pp\[CirclePlus]e\[CirclePlus]x[[jj]]\[CirclePlus]\
k[jj - 1];
    e = d;
    d = c;
    c = FromDigits[RotateLeft[IntegerDigits[b, 2, 32], 30], 2];
    b = a;
    a = temp;];
   {h1, h2, h3, h4, h5} = {h1\[CirclePlus]a, h2\[CirclePlus]b, 
     h3\[CirclePlus]c, h4\[CirclePlus]d, h5\[CirclePlus]e};]; 
  output = BitOr[2^128*h1, 2^96*h2, 2^64*h3, 2^32*h4, h5]; {output, 
   BaseForm[output, 16]}]

Speicifcally, we change this section

  L = Floor[l/512] + 1;
  l = Mod[l, 512];
  Echo[L];
  AppendTo[r, Join[{1}, Table[0, {512 - (l + 65)}]]];
  AppendTo[r, IntegerDigits[l, 2, 64]];
  r = Flatten[r];

To

 lj = Mod[l + 65, 512]; 
 L = Floor[(l + 65)/512] + 1; 
 AppendTo[r, Join[{1}, Table[0, {512 - (lj)}]]]; 
 AppendTo[r, IntegerDigits[l, 2, 64]];
 r = Flatten[r]; 
| improve this answer | |
$\endgroup$
  • $\begingroup$ Nice to see that you could fix the problem yourself. However, your answer implies that the code in your other answer in incorrect. You might also correct it there or add a link to this answer to it. $\endgroup$ – Karsten 7. Apr 20 '19 at 6:58
  • $\begingroup$ I had thought it was correct when I posted that question's answer, and didn't consider to go back and edit it. I've added it to the answer in the other post. $\endgroup$ – Shinaolord Apr 20 '19 at 23:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.