johannu

64 Reputation

2 Badges

15 years, 31 days

MaplePrimes Activity


These are answers submitted by johannu

I found a solution at the Department of Mathematics at University of Erlangen (Germany), It's a little bit slow, but it works!

######################################################################
# SHA_1 - Version vom 13.6.2003
# Programmiert nach FIPS 180-2 (2002 August 1)
######################################################################
# Ein Wort w ist hier (SHA-1) 32 Bits lang, es wird als Liste der
# Laenge 32 mit Eintraegen 0 oder 1 dargestellt. Ein Wort w entspricht
# einer Zahl zwischen 0 und 2^32-1. Die Funktionen SHA_wort2zahl und
# SHA_zahl2wort nehmen die Umwandlung vor.
######################################################################
# Funktionen:
# SHA_zahl2wort:=proc()
# SHA_wort2zahl:=proc()
# SHA_ROTL:=proc()
# SHA_oplus:=proc()
# SHA_und:=proc()
# SHA_nicht:=proc()
# SHA_1_f:=proc()
# SHA_1:=proc()
# hash:=proc()
######################################################################

SHA_zahl2wort:=proc()
  local z, w, i;
  z:=args[1]; w:=[];
  for i from 1 to 32 do
    w:=[z mod 2,op(w)]; z:=iquo(z,2);
  od;
  w;
end:

SHA_wort2zahl:=proc()
  local w, z, i;
  w:=args[1]; z:=0;
  for i from 1 to 32 do
    z:=2*z+w[i];
  od;
  z;
end:

# Zirkulaerer Linksshift, angewandt auf Wort
# SHA_ROTL(w) einmaliger Linksshift, SHA_ROTL(n,w) n-maliger Linksshift
SHA_ROTL:=proc()
  local w, w1, n, i;
  if nargs=1 then
    w:=args[1];
    w1:=w[1]; w:=subsop(1=NULL,w); w:=[op(w),w1];
  else
    n:=args[1]; w:=args[2];
    for i from 1 to n do
      w:=SHA_ROTL(w);
    od;
  fi;
  w;
end:

# Addition modulo 2 zweier Listen
SHA_oplus:=proc()
  local w1, w2, w, i;
  w1:=args[1]; w2:=args[2]; w:=[];
  for i from 1 to nops(w1) do
    w:=[op(w),(w1[i]+w2[i]) mod 2];
  od;
  w;
end:

# UND zweier Listen
SHA_und:=proc()
  local w1, w2, w, i;
  w1:=args[1]; w2:=args[2]; w:=[];
  for i from 1 to nops(w1) do
    w:=[op(w),(w1[i]*w2[i]) mod 2];
  od;
  w;
end:

# NICHT einer Liste
SHA_nicht:=proc()
  map(x->(1-x) mod 2,args[1]);
end:

# SHA-1-Funktionen f(t,x,y,z) mit 0<=t<=79, x,y,z sind Zahlen, die
# Worten entsprechen
SHA_1_f:=proc()
  local t, x, y, z, w;
  t:=args[1];
  x:=SHA_zahl2wort(args[2]);
  y:=SHA_zahl2wort(args[3]);
  z:=SHA_zahl2wort(args[4]);
  if t<20 then
    w:=SHA_oplus(SHA_und(x,y),SHA_und(SHA_nicht(x),z));
  elif t<40 then
    w:=SHA_oplus(SHA_oplus(x,y),z);
  elif t<60 then
    w:=SHA_oplus(SHA_oplus(SHA_und(x,y),SHA_und(x,z)),SHA_und(y,z));
  else
    w:=SHA_oplus(SHA_oplus(x,y),z);
  fi;
  SHA_wort2zahl(w);
end:

# Eingabe: Bytefolge oder String
SHA_1:=proc()
  local M, W, k, l, ll, i, MM, M_i, K, t, H_0, H_1, H_2, H_3, H_4, j,
        a, b, c, d, e, T, H, h, z;
  M:=args[1];
  if type(M,string) then M:=convert(M,bytes); fi;
  W:=array(0..79);

  ####################################################################
  # Padding ##########################################################
  ####################################################################

  # Setze k=(-nops(M)-9 mod 64
  k:=(-nops(M)-9) mod 64;

  # Wandle die Zahl 8*nops(M) (Bit-Laenge von M) in 8 Bytes ll um.
  l:=8*nops(M); ll:=[];
  for i from 1 to 8 do
    ll:=[l mod 256,op(ll)]; l:=iquo(l,256);
  od;

  # Haenge an M das Byte 128 an, was der Bitfolge [1,0,0,0,0,0,0,0]
  # entspricht.
  M:=[op(M),128];

  # Haenge an M k-mal ein Byte 0 an.
  for i from 1 to k do
    M:=[op(M),0];
  od;

  # Haenge an M die 8 Bytes ll an. Das neue M sollte jetzt eine
  # durch 64 teilbare Bytezahl haben.
  M:=[op(M),op(ll)];

  ####################################################################
  # Aufteilung von M in 64-Byte-Bloecke MM[1],MM[2],MM[3],... ########
  ####################################################################

  MM:=[]; M_i:=[];
  for i from 1 to nops(M) do
    M_i:=[op(M_i),M[i]];
    if i mod 64=0 then MM:=[op(MM),M_i]; M_i:=[]; fi;
  od;

  ####################################################################
  # SHA-1-Konstanten #################################################
  ####################################################################

  K:=array(0..79);
  for t from  0 to 19 do K[t]:=convert("5a827999",decimal,hex); od;
  for t from 20 to 39 do K[t]:=convert("6ed9eba1",decimal,hex); od;
  for t from 40 to 59 do K[t]:=convert("8f1bbcdc",decimal,hex); od;
  for t from 60 to 79 do K[t]:=convert("ca62c1d6",decimal,hex); od;
 
  ####################################################################
  # Berechnung der Hash-Werte ########################################
  ####################################################################
 
  # Initial Hash Values
  H_0:=convert("67452301",decimal,hex);
  H_1:=convert("efcdab89",decimal,hex);
  H_2:=convert("98badcfe",decimal,hex);
  H_3:=convert("10325476",decimal,hex);
  H_4:=convert("c3d2e1f0",decimal,hex);

  # Fuer jeden 64-Byte-Block M=MM[i] werden nacheinander folgende
  # Schritte ausgefuehrt.
  for i from 1 to nops(MM) do

    # 1. Schritt
    M:=MM[i];
    # M hat 64 Bytes, dies wird in 16 Bloecke mit je 4 Bytes, also in 16
    # Worte W[0],...,W[15] aufgeteilt, die aber als Zahlen dargestellt
    # werden
    for t from 0 to 15 do
      W[t]:=0;
      for j from 1 to 4 do
        W[t]:=W[t]+M[t*4+j]*256^(4-j);
      od;
    od;

    # W[16],...W[79] ergeben sich folgendermassen.
    for t from 16 to 79 do
      W[t]:=SHA_wort2zahl(SHA_ROTL(SHA_oplus(SHA_oplus(SHA_oplus(
        SHA_zahl2wort(W[t-3]),SHA_zahl2wort(W[t-8])),SHA_zahl2wort(
        W[t-14])),SHA_zahl2wort(W[t-16]))));
    od;
 
    # 2. Schritt
    a:=H_0;
    b:=H_1;
    c:=H_2;
    d:=H_3;
    e:=H_4;
 
    # 3. Schritt
    for t from 0 to 79 do
      T:=(SHA_wort2zahl(SHA_ROTL(5,SHA_zahl2wort(a)))+SHA_1_f(t,b,c,d)
          +e+K[t]+W[t]) mod 2^32;
      e:=d;
      d:=c;
      c:=SHA_wort2zahl(SHA_ROTL(30,SHA_zahl2wort(b)));
      b:=a;
      a:=T;
      if 1=0 then
        printf("%8s  ",convert(convert(a,hex),string));
        printf("%8s  ",convert(convert(b,hex),string));
        printf("%8s  ",convert(convert(c,hex),string));
        printf("%8s  ",convert(convert(d,hex),string));
        printf("%8s\n",convert(convert(e,hex),string));
      fi;
    od;

    # 4. Schritt
    H_0:=(a+H_0) mod 2^32;
    H_1:=(b+H_1) mod 2^32;
    H_2:=(c+H_2) mod 2^32;
    H_3:=(d+H_3) mod 2^32;
    H_4:=(e+H_4) mod 2^32;

  od;
  H:=H_0*2^128+H_1*2^96+H_2*2^64+H_3*2^32+H_4;

  # Umwandlung des Hashwertes H in Hexadezimaldarstellung
  h:=[];
  for i from 1 to 40 do
    z:=H mod 16; H:=iquo(H,16);
    if z<10 then h:=[z+48,op(h)]; else h:=[z+87,op(h)]; fi;
  od;
  convert(h,bytes);
end:

# Test-Strings:
if 1=0 then
  s1:="abc";
  h1:="a9993e364706816aba3e25717850c26c9cd0d89d";
  s2:="abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
  h2:="84983e441c3bd26ebaae4aa1f95129e5e54670f1";
  #s3:=convert([seq(97,i=1..1000000)],bytes):
  # h3
  if SHA_1(s2)<>h2 then
    printf("Fehler!\n");
  else
    printf("o.k.\n");
  fi;
fi:

# hash(...,n) liefert die ersten n Hexadezimalstellen von SHA_1(...).
hash:=proc()
  local n, h, h_n, i;
  if nargs=1 then n:=40; else n:=args[2]; fi;
  h:=convert(SHA_1(args[1]),bytes);
  h_n:=[];
  for i from 1 to n do h_n:=[op(h_n),h[i]]; od;
  convert(h_n,bytes);
end;

######################################################################
 

 

Thank you very much, it works.

But when I take the result of decimal-hex-conversion (convert(decimal,hex), I get an error of inavlid input, saying that the 1st argument x to be of set string, but recieved 18DBD3547552C73BE4DE87731C500.

How to solve this problem?

The procedure should pad so much zeros, that it is always 16 Byte long, that means to have a length of 32. In the example given the lenght is 29.

I found the solution for the above problem and adapted your procedure to the lenght of 32. Thank you!

Johann

This is no error. The content is not displayed. It works.

 

Thank you.

Johann

If I want to define a 2x24 matrix, I get an error. With your 2x7 matrix it works. Where is the problem? Johann
Page 1 of 1