MD5-Hashes mit FastFile?

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

In pellesC neues Projekt anlegen, "statische lib". Alle *.c und *.h
hinzufügen und kompilieren. Wenn nicht allzuviele Fehlermeldungen
kommen, könnte es klappen. Anhand der Headerdateien kannst
sehen wie Dein Import auszusehen hat.

Du kannst dabei ja nichts kaputt machen :mrgreen:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Beitrag von Helle »

Hier die Umsetzung des Wikipedia Pseudocodes für MD5 in Assembler. Es ist noch etlicher Spielraum für Optimierungen!

Code: Alles auswählen

;- MD5 selbst berechnen
;- basierend auf den Pseudocode von Wikipedia "Message-Digest Algorithm 5", damit für x86 brauchbar auf Little Endian umgestellt 
;- Soll nur als Beispiel dienen, unoptimiert und für Zeiger-Ermittlung wären Strukturen für die Werte angebracht
;- "Helle" Klaus Helbing, 24.08.2007, PB4.02

Global Message$="Franz jagt im komplett verwahrlosten Taxi quer durch Bayern"
                
Procedure.s MD5_ASM(StringAdresse, StringLaenge)
;- Rotations-Werte, hier einzeln
Global R00.l= 7
Global R01.l=12
Global R02.l=17
Global R03.l=22 
Global R04.l= 7
Global R05.l=12
Global R06.l=17
Global R07.l=22 
Global R08.l= 7
Global R09.l=12
Global R10.l=17
Global R11.l=22 
Global R12.l= 7
Global R13.l=12
Global R14.l=17
Global R15.l=22 
Global R16.l= 5
Global R17.l= 9
Global R18.l=14
Global R19.l=20
Global R20.l= 5
Global R21.l= 9
Global R22.l=14
Global R23.l=20
Global R24.l= 5
Global R25.l= 9
Global R26.l=14
Global R27.l=20
Global R28.l= 5
Global R29.l= 9
Global R30.l=14
Global R31.l=20
Global R32.l= 4
Global R33.l=11
Global R34.l=16
Global R35.l=23
Global R36.l= 4
Global R37.l=11
Global R38.l=16
Global R39.l=23
Global R40.l= 4
Global R41.l=11
Global R42.l=16
Global R43.l=23
Global R44.l= 4
Global R45.l=11
Global R46.l=16
Global R47.l=23
Global R48.l= 6
Global R49.l=10
Global R50.l=15
Global R51.l=21
Global R52.l= 6
Global R53.l=10
Global R54.l=15
Global R55.l=21
Global R56.l= 6
Global R57.l=10
Global R58.l=15
Global R59.l=21
Global R60.l= 6
Global R61.l=10
Global R62.l=15
Global R63.l=21

;- Sinus-Werte
Global K00.l=$d76aa478
Global K01.l=$e8c7b756
Global K02.l=$242070db
Global K03.l=$c1bdceee
Global K04.l=$f57c0faf
Global K05.l=$4787c62a
Global K06.l=$a8304613
Global K07.l=$fd469501
Global K08.l=$698098d8
Global K09.l=$8b44f7af
Global K10.l=$ffff5bb1
Global K11.l=$895cd7be
Global K12.l=$6b901122
Global K13.l=$fd987193
Global K14.l=$a679438e
Global K15.l=$49b40821
Global K16.l=$f61e2562
Global K17.l=$c040b340
Global K18.l=$265e5a51
Global K19.l=$e9b6c7aa
Global K20.l=$d62f105d
Global K21.l=$02441453
Global K22.l=$d8a1e681
Global K23.l=$e7d3fbc8
Global K24.l=$21e1cde6
Global K25.l=$c33707d6
Global K26.l=$f4d50d87
Global K27.l=$455a14ed
Global K28.l=$a9e3e905
Global K29.l=$fcefa3f8
Global K30.l=$676f02d9
Global K31.l=$8d2a4c8a
Global K32.l=$fffa3942
Global K33.l=$8771f681
Global K34.l=$6d9d6122
Global K35.l=$fde5380c
Global K36.l=$a4beea44
Global K37.l=$4bdecfa9
Global K38.l=$f6bb4b60
Global K39.l=$bebfbc70
Global K40.l=$289b7ec6
Global K41.l=$eaa127fa
Global K42.l=$d4ef3085
Global K43.l=$04881d05
Global K44.l=$d9d4d039
Global K45.l=$e6db99e5
Global K46.l=$1fa27cf8
Global K47.l=$c4ac5665
Global K48.l=$f4292244
Global K49.l=$432aff97
Global K50.l=$ab9423a7
Global K51.l=$fc93a039
Global K52.l=$655b59c3
Global K53.l=$8f0ccc92
Global K54.l=$ffeff47d
Global K55.l=$85845dd1
Global K56.l=$6fa87e4f
Global K57.l=$fe2ce6e0
Global K58.l=$a3014314
Global K59.l=$4e0811a1
Global K60.l=$f7537e82
Global K61.l=$bd3af235
Global K62.l=$2ad7d2bb
Global K63.l=$eb86d391

;- Start-Werte
Global H0.l= $67452301
Global H1.l= $efcdab89
Global H2.l= $98badcfe
Global H3.l= $10325476

;- Hex-Anzeige
Global S0.l= $33323130  
Global S1.l= $37363534
Global S2.l= $62613938
Global S3.l= $66656463

Global A.l
Global B.l
Global C.l
Global D.l

Global Temp.l

Global Buffer.l

Global Message_Laenge.l
Global Message_Pointer.l

Global MD5_ASM$=Space(32)

!mov eax,[p.v_StringLaenge]
!mov [v_Message_Laenge],eax

Buffer=AllocateMemory(Message_Laenge+64)    ;64 Byte=512 Bit kann maximal hinzukommen

!mov edi,[v_Buffer]

!mov ecx,[v_Message_Laenge] 
!or ecx,ecx
!jz l_nullstring
!mov esi,[p.v_StringAdresse] 
!cld
!@@:
!movsb                       ;den String in den Buffer kopieren; erstmal byte-weise (langsam!)
!dec ecx
!jnz @b

NullString:

!mov byte[edi],10000000b     ;das eine Bit setzen

!mov eax,[v_Message_Laenge]
!xor edx,edx
!shl eax,1                   ;muss irgendwie schneller gehen
!adc edx,0
!shl edx,1
!shl eax,1
!adc edx,0
!shl edx,1
!shl eax,1
!adc edx,0
;!shl edx,1                 ;Edit: Dies ist zuviel!  26.08.2007

!mov ebx,[v_Message_Laenge]
 
!@@:
!inc edi
!inc ebx
!mov ecx,ebx
!and ecx,111111b
!cmp ecx,56
!jne @b

!mov [edi],eax               ;Low-Bits Message_Laenge
!mov [edi+4],edx             ;High-Bits Message_Laenge

;- Anzahl der Blöcke berechnen
!add edi,8
!sub edi,[v_Buffer]
!mov ebp,edi
!shr ebp,6                   ;epb=Blockzähler

Noch_ein_Block:
;-Block initialisieren
!mov eax,[v_H0]
!mov [v_A],eax
!mov eax,[v_H1]
!mov [v_B],eax
!mov eax,[v_H2]
!mov [v_C],eax
!mov eax,[v_H3]
!mov [v_D],eax

!xor ebx,ebx                 ;0 bis 63 für einen Block
Hauptschleife:
;------------------
!cmp ebx,15                  ;alles einzeln kann auch nicht besonders schnell sein
!ja @f
!mov edi,[v_B]
!mov edx,edi
!and edi,[v_C]
!not edx
!and edx,[v_D]
!or edi,edx                  ;edi=f

!mov esi,ebx                 ;esi=g
!jmp l_blockviertel_ende
;------------------ 
!@@:
!cmp ebx,31
!ja @f
!mov edi,[v_D]
!mov edx,edi
!and edi,[v_B]
!not edx
!and edx,[v_C]
!or edi,edx

!mov esi,ebx
!shl esi,2
!add esi,ebx
!inc esi
!and esi,15                  ;MOD 16

!jmp l_blockviertel_ende
;------------------
!@@:
!cmp ebx,47
!ja @f
!mov edi,[v_B]
!xor edi,[v_C]
!xor edi,[v_D]

!mov esi,ebx
!shl esi,1
!add esi,ebx
!add esi,5
!and esi,15

!jmp l_blockviertel_ende
;------------------
!@@:
!mov eax,[v_D]
!not eax
!mov ecx,[v_B]
!or ecx,eax
!mov edi,[v_C]
!xor edi,ecx

!mov esi,ebx
!shl esi,3
!sub esi,ebx
!and esi,15
;------------------

Blockviertel_Ende:
!mov eax,[v_D]
!mov [v_Temp],eax

!mov eax,[v_C]
!mov [v_D],eax

!mov eax,[v_B]
!mov [v_C],eax

!lea edx,[v_K00]
!mov eax,[edx+ebx*4]         ;k
!mov edx,[v_Buffer]
!add eax,[edx+esi*4]         ;w   esi=g
!add eax,[v_A]
!add eax,edi                 ;edi=f    
!mov ecx,ebx
!lea edx,[v_R00]
!mov ecx,[edx+ecx*4]
!rol eax,cl
!add eax,[v_B]
!mov [v_B],eax

!mov eax,[v_Temp]
!mov [v_A],eax

!inc ebx
!cmp ebx,64
!jb l_hauptschleife

;------------------
!mov eax,[v_A]
!add [v_H0],eax
!mov eax,[v_B]
!add [v_H1],eax
!mov eax,[v_C]
!add [v_H2],eax
!mov eax,[v_D]
!add [v_H3],eax

!mov eax,[v_Buffer]
!add eax,64
!mov [v_Buffer],eax
  
;- Test ob noch ein Block
!dec ebp
!jnz l_noch_ein_block

;-------- Ende ----
;- für Anzeige
Temp=@MD5_ASM$               ;Temp ist für alles gut!
!mov edi,[v_Temp]
!xor eax,eax
!mov ebx,eax
!mov ecx,eax
!lea esi,[v_S0]
!lea edx,[v_H0]
!mov ebp,16                  ;16 Bytes (H0 bis H3) einlesen und in 32-Byte-Hex-String umwandeln

!@@:
!mov bl,byte[edx]            ;lässt sich bestimmt auch noch optimieren
!mov cl,bl
!and bl,0f0h
!shr bl,4
!mov al,[esi+ebx]
!mov [edi],al
!inc edi
!and cl,0fh
!mov al,[esi+ecx]
!mov [edi],al
!inc edi
!inc edx
!dec ebp
!jnz @b 
   
 ProcedureReturn MD5_ASM$ 
EndProcedure 

;---------------------------------------------------
TASMA=ElapsedMilliseconds()
For i=0 To 99999
ASM$=MD5_ASM(@Message$, Len(Message$))
Next
TASME=ElapsedMilliseconds()-TASMA

TPBA=ElapsedMilliseconds()
For i=0 To 99999
PB$=MD5Fingerprint(@Message$, Len(Message$))
Next
TPBE=ElapsedMilliseconds()-TPBA

MessageRequester("MD5", "Ausgangs-String : "+Message$+#LFCR$+"ASM : "+ASM$+"   in "+Str(TASME)+" ms"+#LFCR$+"PB :    "+PB$+"   in "+Str(TPBE)+" ms")
Gruß
Helle
Zuletzt geändert von Helle am 26.08.2007 20:04, insgesamt 1-mal geändert.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

@Helle:
Kann man den Rotationskram und die Sinuswerte nicht in DataSections oder
Protected Arrays packen?
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Beitrag von Helle »

@Nic: Schön, das du (zumindest im Momemt) wieder Zeit für´s Forum hast :allright: !
Allgemein zum Code: In ASM-Programmen verwende ich für Variablen usw. die data-section vom FAsm (kennste ja); ich habe aber den Eindruck, dies kommt bei den nicht so ASM-sattelfesten Usern hier nicht so gut an, deshalb wandle ich dies dann zur Veröffentlichung in (meist) globale PB-Variablen um. Im obigen Fall kann natürlich auch die PB-DataSection verwendet werden, würde wohl auch optisch besser aussehen. Protected fällt in Schleifen aus, denn in jedem Schleifendurchlauf würden die Daten auf den Stack geschoben; nichts mehr mit schneller (Schleifen-)Ausführungszeit! Das ist hier die Zwickmühle: Mit ´ner schnellen Testzeit (eben in einer Schleife ermittelt) angeben oder (mitunter durchaus sinnvoll) protected Variablen verwenden. Dies sollte übrigens auch bei Prozeduren beachtet werden, die im Programm häufiger aufgerufen werden.
Ergänzung noch zum obigen Code: Ein schöner Geschwindigkeitsschub ergibt sich in der Variante ohne Umkopieren des Strings.

Gruß
Helle
Benutzeravatar
PureBasic4.0
Beiträge: 785
Registriert: 29.10.2006 17:26
Wohnort: 127.0.0.1

Beitrag von PureBasic4.0 »

den Code werde ich mir morgen mal anschauen. Gute Arbeit! :allright:
PB 4.50 RC1 + Ubuntu 10.04 LTS + Windows 7 x64
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Den Geschwindigkeitsverlust von Protected Variablen kann man doch durch
Static Variablen umgehen.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Beitrag von Helle »

@ts: Natürlich richtig. Da es aber "nur" um die Vermeidung von Namens-Kollisionen geht schlägt hier meine natürliche Faulheit zu: Eine globale Variable spreche ich mit ASM so an:

Code: Alles auswählen

[v_Variable]
In einer Prozedur mit Namen "Dies_ist_eine_Procedure" müsste ich für eine static Variable schreiben:

Code: Alles auswählen

[s_Dies_ist_eine_Procedure.v_Variable]
Das kann keiner verlangen :mrgreen: !

Gruß
Helle
Benutzeravatar
HeX0R
Beiträge: 3042
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Beitrag von HeX0R »

Das hier ist übrigens schneller und auch nicht vollgepackt mit hunderten von globalen Variablen und daher angenehmer im Eigengebrauch.
Hab ich auch in meinem MD5 Bruteforcer in etwas veränderter Form verwendet.
Antworten