I'm trying to write a sha256 implementation in pure pascal like sha1 and
md5 units.
With negative results.

Someone can helpme with this?



-- 
H. Gabriel Máculus
http://twitter.com/gabrielix - https://prism-break.org/
<http://github.com/gabrielix/>
program sha256_test;
{$mode objfpc}{$h+}

Type 
  TSHA256Digest = array[0..32] Of Byte;

  TSHA256Context = record
		      State   : array[0..7] of Cardinal;
		      data    : array[0..63] of Byte;
		      datalen : cardinal;
		      bitlen  : qword;
  end;			      

const
   HexTable: array[0..15] of char='0123456789abcdef';

  h0 : cardinal = $6a09e667;
  h1 : cardinal = $bb67ae85;
  h2 : cardinal = $3c6ef372;
  h3 : cardinal = $a54ff53a;
  h4 : cardinal = $510e527f;
  h5 : cardinal = $9b05688c;
  h6 : cardinal = $1f83d9ab;
  h7 : cardinal = $5be0cd19;


k :array[0..63] Of cardinal = (
                                  $428a2f98, $71374491, $b5c0fbcf, $e9b5dba5, $3956c25b, $59f111f1,
                                  $923f82a4, $ab1c5ed5,
                                  $d807aa98, $12835b01, $243185be, $550c7dc3, $72be5d74, $80deb1fe,
                                  $9bdc06a7, $c19bf174,
                                  $e49b69c1, $efbe4786, $0fc19dc6, $240ca1cc, $2de92c6f, $4a7484aa,
                                  $5cb0a9dc, $76f988da,
                                  $983e5152, $a831c66d, $b00327c8, $bf597fc7, $c6e00bf3, $d5a79147,
                                  $06ca6351, $14292967,
                                  $27b70a85, $2e1b2138, $4d2c6dfc, $53380d13, $650a7354, $766a0abb,
                                  $81c2c92e, $92722c85,
                                  $a2bfe8a1, $a81a664b, $c24b8b70, $c76c51a3, $d192e819, $d6990624,
                                  $f40e3585, $106aa070,
                                  $19a4c116, $1e376c08, $2748774c, $34b0bcb5, $391c0cb3, $4ed8aa4a,
                                  $5b9cca4f, $682e6ff3,
                                  $748f82ee, $78a5636f, $84c87814, $8cc70208, $90befffa, $a4506ceb,
                                  $bef9a3f7, $c67178f2);


function rotl(a	: cardinal; n : byte) : cardinal;
begin
   rotl := (a shl n) or (a shr (32 - n));
end;

function rotr(a	: cardinal; n : byte) : cardinal;
begin
   rotr := (a shr n) or (a shl (32 - n));
end;

function ch(x, y, z : cardinal) : cardinal;
begin
   ch := (( (x) and (y) ) xor ( not (x) and (z)));
end;

function maj(x, y, z : cardinal) : cardinal;
begin
   maj := (((x) and (y)) xor ((x) and (z)) xor ((y) and (z)));
end;

function ep0(x : cardinal) : cardinal;
begin
   ep0 := (rotr(x,2) xor rotr(x,13) xor rotr(x,22));
end;

function ep1(x : cardinal) : cardinal;
begin
   ep1 := (rotr(x,6) xor rotr(x,11) xor rotr(x,25));
end;

function sig0(x : cardinal) : cardinal;
begin
   sig0 := (rotr(x,7) xor rotr(x,18) xor (x shr 3));
end;

function sig1(x : cardinal) : cardinal;
begin
   sig1 := (rotr(x,17) xor rotr(x,19) xor (x shr 10));
end;

procedure sha256_transform(var ctx : TSHA256Context; var data : array of byte);
var
   a, b, c, d, e, f, g, h, i, j, t1, t2	: cardinal;
   m					: array[0..63] of byte;

begin
   j := 0;
   for i := 0 to 15 do
   begin
      m[i] := (data[j] shl 24) or (data[j + 1] shl 16) or (data[j + 2] shl 8) or (data[j + 3]);
      inc(j, 4);
   end;

   j := 0;
   for i:= 0 to 15 do
   begin
      m[i] := (data[j] shl 24) or (data[j + 1] shl 16) or (data[j + 2] shl 8) or (data[j + 3]);
   end;

   for i:=16 to 63 do
   begin
      m[i] := sig1(m[i - 2]) + m[i - 7] + sig0(m[i - 15]) + m[i - 16];
   end;

   a := ctx.state[0];
   b := ctx.state[1];
   c := ctx.state[2];
   d := ctx.state[3];
   e := ctx.state[4];
   f := ctx.state[5];
   g := ctx.state[6];
   h := ctx.state[7];

   for i := 0 to 63 do
   begin
      t1 := h + ep1(e) + ch(e, f, g) + k[i] + m[i];
      t2 := ep0(a) + maj(a,b,c);
      h := g;
      g := f;
      f := e;
      e := d + t1;
      d := c;
      c := b;
      b := a;
      a := t1 + t2;
   end;

   ctx.state[0] := ctx.state[0] + a;
   ctx.state[1] := ctx.state[1] + b;
   ctx.state[2] := ctx.state[2] + c;
   ctx.state[3] := ctx.state[3] + d;
   ctx.state[4] := ctx.state[4] + e;
   ctx.state[5] := ctx.state[5] + f;
   ctx.state[6] := ctx.state[6] + g;
   ctx.state[7] := ctx.state[7] + h;

end;

procedure sha256_init(var ctx : TSHA256Context);
begin
	ctx.datalen := 0;
	ctx.bitlen := 0;
	ctx.state[0] := $6a09e667;
	ctx.state[1] := $bb67ae85;
	ctx.state[2] := $3c6ef372;
	ctx.state[3] := $a54ff53a;
	ctx.state[4] := $510e527f;
	ctx.state[5] := $9b05688c;
	ctx.state[6] := $1f83d9ab;
	ctx.state[7] := $5be0cd19;
end;


procedure sha256_update(var ctx : TSHA256Context; var data : array of byte; len : cardinal);
var
   i :cardinal;
begin
   for i:=0 to (len-1) do
   begin
      ctx.data[ctx.datalen] := data[i];
      inc(ctx.datalen);
      if ctx.datalen = 64 then
      begin
	 sha256_transform(ctx, ctx.data);
	 inc(ctx.bitlen, 512);
	 ctx.datalen := 0;
      end;
   end;
end;

procedure sha256_final(var ctx : TSHA256Context; var hash : array of byte);
var
   i : cardinal;
begin

   i := ctx.datalen;

   // Pad whatever data is left in the buffer.
   if ctx.datalen < 56 then
   begin
      ctx.data[i] := $80;
      inc(i);
      while i < 56 do
      begin
	 ctx.data[i] := $00;
	 inc(i);
      end;
   end	
   else 
   begin
      ctx.data[i] := $80;
      inc(i);
      while i < 64 do
      begin
	 ctx.data[i] := $00;
	 inc(i);
      end;
      sha256_transform(ctx, ctx.data);
      fillbyte(ctx.data, 56, 0);
   end;	

      ctx.bitlen := ctx.bitlen + (ctx.datalen * 8);
      ctx.data[63] := ctx.bitlen;
      ctx.data[62] := ctx.bitlen shr 8;
      ctx.data[61] := ctx.bitlen shr 16;
      ctx.data[60] := ctx.bitlen shr 24;
      ctx.data[59] := ctx.bitlen shr 32;
      ctx.data[58] := ctx.bitlen shr 40;
      ctx.data[57] := ctx.bitlen shr 48;
      ctx.data[56] := ctx.bitlen shr 56;
      sha256_transform(ctx, ctx.data);

      for i := 0 to 3 do
      begin
	 hash[i]      := (ctx.state[0] shr (24 - i * 8)) and $000000ff;
	 hash[i + 4]  := (ctx.state[1] shr (24 - i * 8)) and $000000ff;
	 hash[i + 8]  := (ctx.state[2] shr (24 - i * 8)) and $000000ff;
	 hash[i + 12] := (ctx.state[3] shr (24 - i * 8)) and $000000ff;
	 hash[i + 16] := (ctx.state[4] shr (24 - i * 8)) and $000000ff;
	 hash[i + 20] := (ctx.state[5] shr (24 - i * 8)) and $000000ff;
	 hash[i + 24] := (ctx.state[6] shr (24 - i * 8)) and $000000ff;
	 hash[i + 28] := (ctx.state[7] shr (24 - i * 8)) and $000000ff;
      end;
end;	

var
   myctx   : TSHA256Context;
   datos   : array[0..1] of byte = (ord('b'), ord('a'));
   salida  : array[0..31] of byte;
   i	   : integer;
   compose : char;
   p	   : pchar;
begin
   sha256_init(myctx);
   sha256_update(myctx, datos, 2);
   sha256_final(myctx, salida);

   i :=0;
   repeat
      write(hextable[(salida[i] shr 4) and 15],
	    hextable[salida[i] and 15]
	    );
      inc(i);
   until i = 32;
   writeln;


end.
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to