Einzelnen Beitrag anzeigen

Assarbad
(Gast)

n/a Beiträge
 
#1

Message-Digest MD5 optimiert für Delphi

  Alt 1. Sep 2003, 00:51
Hiho,

für unser Projekt DoubleKiller habe ich die C-Dateien aus der RFC1321 übersetzt und ein wenig optimiert (schließlich hat Delphi keinen Präprozessor und Makros).
Wer sich fragt, warum ich Assembler benutzt habe ... 1. weil Delphi keine Makros kennt und normale Funktionen einen Prolog und einen Epilog haben 2. weil Delphi den ersten Code, den ich geschrieben hatte ineffizient umgesetzt hatte 3. weil dieser Code auf große Datenmengen angewandt werden soll.

Download hier (enthält die RFC):
http://assarbad.net/stuff/!export/md5.rar
http://assarbad.net/stuff/!export/md5.zip

Der Code ist zu lang um ihn hier komplett wiederzugeben, deshalb nur ein paar der Kernroutinen bzw DIE Kernroutinen:

Delphi-Quellcode:
// RSA Data Security, Inc., MD5 message-digest algorithm

function F(X, Y, Z: DWORD): DWORD; register;
// #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
(* EAX = X; EDX = Y; ECX = Z *)
asm
  PUSH EAX
  AND EDX, EAX
  POP EAX
  NOT EAX
  AND EAX, ECX
  OR EAX, EDX
end;

function G(X, Y, Z: DWORD): DWORD; register;
// #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
(* EAX = X; EDX = Y; ECX = Z *)
asm
  PUSH ECX
  AND EAX, ECX
  POP ECX
  NOT ECX
  AND EDX, ECX
  OR EAX, EDX
end;

function H(X, Y, Z: DWORD): DWORD; register;
// #define H(x, y, z) ((x) ^ (y) ^ (z))
(* EAX = X; EDX = Y; ECX = Z *)
asm
  XOR EDX, ECX
  XOR EAX, EDX
end;

function I(X, Y, Z: DWORD): DWORD; register;
// #define I(x, y, z) ((y) ^ ((x) | (~z)))
(* EAX = X; EDX = Y; ECX = Z *)
asm
  NOT ECX
  OR EAX, ECX
  XOR EAX, EDX
end;

procedure Rounds(var A: DWORD; B, C, D, X: DWORD; S: Byte; AC: DWORD; Func: Pointer); register;
// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
// Rotation is separate from addition to prevent recomputation.
(*
#define FuncFuncF(a, b, c, d, x, s, ac) { \
(a) += Func ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \  }
*)

asm
  PUSH EDX // save B
  PUSH EAX // save @A
  MOV EAX, EDX // EAX:=B
  MOV EDX, ECX // EDX:=C
  MOV ECX, D // ECX := D
  CALL Func // Call the function given as a pointer. It depends on the round!
  POP EDX // restore @A
  PUSH EDX // save @A
  ADD EAX, [EDX] // EAX:=A + F(B,C,D)
  ADD EAX, X // ... + X
  ADD EAX, AC // ... + AC
  MOVZX ECX, S // EDX:=S
  ROL EAX, CL
// CALL ROTATE_LEFT // <- replaced by 1 ROL op ... see above.
  POP EDX // restore @A
  POP ECX // restore B
  ADD EAX, ECX // A:=A+B
  MOV [EDX], EAX
// A := ROTATE_LEFT(A + Func(B, C, D) + X + AC, S) + B;
end;
[edit=Sharky]Auf Wunsch den Link zum ACE-Archiv entfernt Mfg, Sharky[/edit]
  Mit Zitat antworten Zitat