Page 1 of 1
sha1 fingerprint string
Posted: Sat Aug 04, 2007 2:17 am
by eddy
Check if it works ...
Make some tests :
http://outils-en-ligne.uzabnet.com/gene ... -ligne.php
Code: Select all
;{ FUNCTIONS AND MARCO }
;circular 32bits left shift
Procedure.l ROL(val, shift)
Protected v1.q = 0
PokeL(@v1,val)
v1 << shift
ProcedureReturn PeekL(@v1) | PeekL(@v1+4)
EndProcedure
Macro STRING_POINTER_(str,posPointer)
Asc(Mid(str,posPointer+1,1))
EndMacro
Macro CPY_ARRAY_(toArr,fromArr,fromArrIndex,length,dataType=Long)
CopyMemory(@fromArr(fromArrIndex),@toArr(0),SizeOf(dataType)*length)
EndMacro
;}
Procedure$ SHA1(in$)
#SHA1_ROUND1 = $5A827999 ;SHA1 Constants
#SHA1_ROUND2 = $6ED9EBA1
#SHA1_ROUND3 = $8F1BBCDC
#SHA1_ROUND4 = $CA62C1D6
Protected h0 = $67452301, h1 = $EFCDAB89, h2 = $98BADCFE ;Intermediate Hash
Protected h3 = $10325476, h4 = $C3D2E1F0 ;Intermediate Hash
Protected a,b,c,d,e ;Word buffer
Protected t ;Temporary word Value
Protected in_length.l = Len(in$)
Protected in_length_quad.q = in_length
Protected datas_length.l = (((in_length + 8) >> 6) + 1) << 4
Dim datas.l(datas_length)
For k=0 To in_length-1
datas(k >> 2) = (datas(k >> 2) << 8) | (STRING_POINTER_(in$,k) & $FF)
Next
datas(in_length >> 2) = ((datas(in_length >> 2)<< 8) | $80) << ((3 - (in_length & 3))<< 3)
datas(datas_length - 2) = (in_length_quad * 8) >> 32
datas(datas_length - 1) = (in_length_quad * 8) & $FFFFFFFF
For chunkStart=0 To datas_length-1 Step 16
a = h0 : b = h1 : c = h2 : d = h3 : e = h4
Dim w.l(80) ;Word sequence
CPY_ARRAY_(w,datas,chunkStart,16) ;Init first 16 Words
For i=16 To 79
w(i) = ROL(w(i - 3) ! w(i - 8) ! w(i - 14) ! w(i - 16), 1)
Next
;Round 1
For i=0 To 19
t = #SHA1_ROUND1 + ROL(a, 5) + (d ! (b & (c ! d))) + e + w(i)
e = d : d = c
c = ROL(b, 30)
b = a : a = t
Next
;Round 2
For i=20 To 39
t = #SHA1_ROUND2 + ROL(a, 5) + (b ! c ! d) + e + w(i)
e = d : d = c
c = ROL(b, 30)
b = a : a = t
Next
;Round 3
For i=40 To 59
t = #SHA1_ROUND3 + ROL(a, 5) + ((b & c) | (d & (b | c))) + e + w(i)
e = d : d = c
c = ROL(b, 30)
b = a : a = t
Next
;Round 4
For i=60 To 79
t = #SHA1_ROUND4 + ROL(a, 5) + (b ! c ! d) + e + w(i)
e = d : d = c
c = ROL(b, 30)
b = a : a = t
Next
h0 + a : h1 + b : h2 + c : h3 + d : h4 + e
Next
ProcedureReturn LCase(RSet(Hex(h0),8,"0") + RSet(Hex(h1),8,"0") + RSet(Hex(h2),8,"0") + RSet(Hex(h3),8,"0") + RSet(Hex(h4),8,"0"))
EndProcedure
If OpenConsole()
PrintN(SHA1("iNiQuiTy"))
PrintN("0a4dd0f633b7e5cd5520bcad12331a65f6b9dac7 ")
Input()
EndIf
BUG FOUND !
Posted: Thu Aug 09, 2007 4:11 am
by CherokeeStalker
This returns only a 39 character result for the string "iNiQuiTy" - no quotes,
not a 40 character result ! It drops the leading '0' !
Result using your code : a4dd0f633b7e5cd5520bcad12331a65f6b9dac7
Result using site above : 0a4dd0f633b7e5cd5520bcad12331a65f6b9dac7
[/b]
Posted: Thu Aug 09, 2007 10:23 pm
by eddy
[bug fixed]
Ok ... It was a little bug.

( HEX conversions at the end of function )
Re: sha1 fingerprint string
Posted: Mon May 17, 2010 6:40 pm
by Karbon
Has anyone else tried this with PB 4.41? I've been looking for an all-PB implementation of SHA1 (yes, I know there is a built in function but I have my reasons

).
I'm getting pretty different results. With his test string :
PB Built-in 0a4dd0f633b7e5cd5520bcad12331a65f6b9dac7
All PB : 0a4dd0f633b7e5cd5520bcad12331a65ffffffff
**** Geeze, if I'd taken 10 seconds to look...
Fixed for PB 4.41 (just changed some variable types to quads)
Code: Select all
;{ FUNCTIONS AND MARCO }
;circular 32bits left shift
Procedure.l ROL(val, shift)
Protected v1.q = 0
PokeL(@v1,val)
v1 << shift
ProcedureReturn PeekL(@v1) | PeekL(@v1+4)
EndProcedure
Macro STRING_POINTER_(str,posPointer)
Asc(Mid(str,posPointer+1,1))
EndMacro
Macro CPY_ARRAY_(toArr,fromArr,fromArrIndex,length,dataType=Long)
CopyMemory(@fromArr(fromArrIndex),@toArr(0),SizeOf(dataType)*length)
EndMacro
;}
Procedure$ SHA1(in$)
#SHA1_ROUND1 = $5A827999 ;SHA1 Constants
#SHA1_ROUND2 = $6ED9EBA1
#SHA1_ROUND3 = $8F1BBCDC
#SHA1_ROUND4 = $CA62C1D6
Protected h0.q = $67452301, h1.q = $EFCDAB89, h2.q = $98BADCFE ;Intermediate Hash
Protected h3.q = $10325476, h4.q = $C3D2E1F0 ;Intermediate Hash
Protected a,b,c,d,e ;Word buffer
Protected t ;Temporary word Value
Protected in_length.l = Len(in$)
Protected in_length_quad.q = in_length
Protected datas_length.l = (((in_length + 8) >> 6) + 1) << 4
Dim datas.l(datas_length)
For k=0 To in_length-1
datas(k >> 2) = (datas(k >> 2) << 8) | (STRING_POINTER_(in$,k) & $FF)
Next
datas(in_length >> 2) = ((datas(in_length >> 2)<< 8) | $80) << ((3 - (in_length & 3))<< 3)
datas(datas_length - 2) = (in_length_quad * 8) >> 32
datas(datas_length - 1) = (in_length_quad * 8) & $FFFFFFFF
For chunkStart=0 To datas_length-1 Step 16
a = h0 : b = h1 : c = h2 : d = h3 : e = h4
Dim w.l(80) ;Word sequence
CPY_ARRAY_(w,datas,chunkStart,16) ;Init first 16 Words
For i=16 To 79
w(i) = ROL(w(i - 3) ! w(i - 8) ! w(i - 14) ! w(i - 16), 1)
Next
;Round 1
For i=0 To 19
t = #SHA1_ROUND1 + ROL(a, 5) + (d ! (b & (c ! d))) + e + w(i)
e = d : d = c
c = ROL(b, 30)
b = a : a = t
Next
;Round 2
For i=20 To 39
t = #SHA1_ROUND2 + ROL(a, 5) + (b ! c ! d) + e + w(i)
e = d : d = c
c = ROL(b, 30)
b = a : a = t
Next
;Round 3
For i=40 To 59
t = #SHA1_ROUND3 + ROL(a, 5) + ((b & c) | (d & (b | c))) + e + w(i)
e = d : d = c
c = ROL(b, 30)
b = a : a = t
Next
;Round 4
For i=60 To 79
t = #SHA1_ROUND4 + ROL(a, 5) + (b ! c ! d) + e + w(i)
e = d : d = c
c = ROL(b, 30)
b = a : a = t
Next
h0 + a : h1 + b : h2 + c : h3 + d : h4 + e
Next
ProcedureReturn LCase(RSet(Hex(h0),8,"0") + RSet(Hex(h1),8,"0") + RSet(Hex(h2),8,"0") + RSet(Hex(h3),8,"0") + RSet(Hex(h4),8,"0"))
EndProcedure
If OpenConsole()
PrintN(SHA1("iNiQuiTy"))
PrintN("0a4dd0f633b7e5cd5520bcad12331a65f6b9dac7 ")
Input()
EndIf
******************** OK, so it's gonna take a little longer than 10 seconds.. Something still isn't right there. If anyone else sees it before I do, let me know!
Re: sha1 fingerprint string
Posted: Mon May 17, 2010 9:47 pm
by SFSxOI
@eddy > your code does not work here - gives different hash for 'iNiQuiTy' then the compared hash. It gives this:
0a4dd0f633b7e5cd5520bcad12331a65ffffffff
0a4dd0f633b7e5cd5520bcad12331a65f6b9dac7
Its all the same up to the end 8 character end when it just gives ffffffff
Re: sha1 fingerprint string
Posted: Mon May 17, 2010 9:53 pm
by Karbon
Are you sure? I've been on the phone since I posted this so I haven't had time to take any sort of a deeper look but this is the result I get :
From the code : 0a4dd0f6133b7e5c5520bcad12331a65f6b9dac7
The Real SHA-1 hash 0a4dd0f633b7e5cd5520bcad12331a65f6b9dac7
differences :
0a4d-d0f6-133b-7e5c-5520-bcad-1233-1a65-f6b9-dac7
************
0a4d-d0f6-33b7-e5cd-5520-bcad-1233-1a65-f6b9-dac7
Notice those differences.. It's *almost* right

Re: sha1 fingerprint string
Posted: Mon May 17, 2010 9:58 pm
by SFSxOI
OK, took a closer look, this is what i get:
0a4dd0f6133b7e5c5520bcad12331a65f6b9dac7
0a4dd0f633b7e5cd5520bcad12331a65f6b9dac7
so yeah, i was mistaken, its almost righ, but not really. it looks about the same at first glance, but when you break it down you see the differences, sorry 'bout that.
Re: sha1 fingerprint string
Posted: Tue May 18, 2010 8:24 am
by infratec
Hi eddy,
found this with an internet search engine

Code: Select all
; German forum: http://www.purebasic.fr/german/viewtopic.php?t=1385&highlight=
; Author: andi256 (updated for PB 4.00 by Andre + Helle)
; Date: 29. December 2004
; OS: Windows
; Demo: Yes
; SHA Algorithmus
; ------------------
; Fingerabdruck (Hashcode) von Daten. Dieser Code hat die Eigenschaft, nicht
; zurückgerechnet werden zu können. Also aus dem Fingerabdruck (zB MD5 oder
; SHA-1) kann der ursprüngliche Datensatz nicht zurückgerechnet werden.
; Das schöne ist, dass auch nur ein verändertes Bit am Ursprungsdatensatz den
; Fingerabdruck stark und fast nicht vorherzusehen verändert. Demnach kann
; man die Integrität von z.B. Dateien etc. testen (Erweiterung dazu ist die
; Digitale Signatur, in der Hashcodes auch eine grosse Rolle spielen).
; Desweiteren kann man Passwörter nur als Fingerabdruck speichern (also nur
; den Hashcode) und später so vorgehen, dass man das eingegebene Passwort
; durch den Hash-Algorithmus jagt und dann das Ergebnis mit dem gespeicherten
; Hash vergleicht. Somit kann man feststellen, ob es das selbe Passwort war.
; Allerdings ist das Passwort selbst nicht wiederherstellbar oder
; herauszufinden und demnach sehr sicher verpackt.
; Weitere Info's zu SHA-1:
; http://de.wikipedia.org/wiki/SHA-1
Global Dim state.l(4)
Global Dim magic.l(4)
Global Dim w.l(80)
;Procedure UpeekB(*mem)
; ProcedureReturn Val(StrU(PeekB(*mem),#PB_Byte))
;EndProcedure
Procedure.s speicherout_hex(*mem,l,q$)
For i = 0 To l-1
q$ = q$ + RSet(Hex(PeekA(*mem+i)),2,"0") + " "
Next i
ProcedureReturn q$
EndProcedure
Procedure toLE(value)
dummy1 = ((value >> 24) & $FF)
dummy2 = ((value >> 8) & $FF00)
dummy3 = ((value & $FF) << 24)
dummy4 = ((value & $FF00) << 8)
dummy5 = dummy1 |dummy2 |dummy3 |dummy4
ProcedureReturn dummy5
EndProcedure
Procedure RotL(num,count) ; rotate left
If count>0 And count<32
!MOV dword ECX,[p.v_count]
!ROL dword [p.v_num],cl
EndIf
ProcedureReturn num
EndProcedure
Procedure f(round,x,y,z)
If round < 20
dummy = ( x & y ) | ( ~x & z )
Else
If round < 40
dummy = ( x ! y ! z )
Else
If round < 60
dummy = ( x & y ) | ( x & z ) | ( y & z )
Else
dummy = ( x ! y ! z )
EndIf
EndIf
EndIf
ProcedureReturn dummy
EndProcedure
Procedure SHA_1(*digest,*buf,len,pad,ende)
magic(0) = $5A827999
magic(1) = $6ED9EBA1
magic(2) = $8F1BBCDC
magic(3) = $CA62C1D6
*databuf = AllocateMemory(64)
state(0) = $67452301
state(1) = $EFCDAB89
state(2) = $98BADCFE
state(3) = $10325476
state(4) = $C3D2E1F0
blocks = (len + 3 + 63) >> 6
bytes_left = len
If (pad|ende) = #True
len=0
Debug "len : " +Str(len)
EndIf
For i=0 To blocks-1
If bytes_left >= 64
CopyMemory(*buf,*databuf, 64)
buf = buf + 64
bytes_left = bytes_left - 64
Else
j=0
If bytes_left > 0
CopyMemory(*buf,*databuf,bytes_left)
j = bytes_left
EndIf
If bytes_left >= 0
PokeB(*databuf+j,Ende)
j = j + 1
bytes_left = -1
EndIf
For j = j To 61
PokeB(*databuf+j,pad)
Next j
If j=62
dummy = ((8*len) >> 8) & $FF
PokeB(*databuf+62,dummy)
j = j + 1
EndIf
If j=63
dummy = (8*len) & $FF
PokeB(*databuf+63,((8*len) & $FF))
EndIf
EndIf
CopyMemory(*databuf,@w(0),64)
For j=0 To 15
w(j)= toLE(w(j))
Next j
For j=16 To 79
w(j) = RotL(w(j-3) ! w(j-8) ! w(j-14) ! w(j-16),1)
Next j
a = state(0)
b = state(1)
c = state(2)
d = state(3)
e = state(4)
For j=0 To 79
t= RotL(a,5) + f(j,b,c,d) + e + w(j) + magic(j/20)
e = d
d = c
c = RotL(b,30)
b = a
a = t
Next j
state(0) = state(0) + a
state(1) = state(1) + b
state(2) = state(2) + c
state(3) = state(3) + d
state(4) = state(4) + e
Next i
state(0) = toLE(state(0))
state(1) = toLE(state(1))
state(2) = toLE(state(2))
state(3) = toLE(state(3))
state(4) = toLE(state(4))
CopyMemory(@state(0),*digest,20)
EndProcedure
OpenConsole()
Input.s = "iNiQuiTy"
;Input.s = "abc"
*digest = AllocateMemory(20)
sha_1(*digest,@input,Len(Input),0,$80)
PrintN(speicherout_hex(*digest,20,"ist : "))
;PrintN ("soll : A9 99 3E 36 47 06 81 6A BA 3E 25 71 78 50 C2 6C 9C D0 D8 9D")
PrintN ("soll : 0a 4d d0 f6 33 b7 e5 cd 55 20 bc ad 12 33 1a 65 f6 b9 da c7")
Input()
CloseConsole()
It works correct.
I made a few modifications for PB 4.41.
The original code is here:
http://www.purearea.net/pb/CodeArchiv/E ... erPrint.pb
It works also with your ROL() procedure.
Best regards,
Bernd
Re: sha1 fingerprint string
Posted: Tue May 18, 2010 1:06 pm
by Karbon
#Byte needs to be #PB_Byte but other than that, yep, it works with 4.41!
Re: sha1 fingerprint string
Posted: Tue May 18, 2010 1:16 pm
by infratec
Hi Karbon,
oh, mistake by me.
I first changed it to #PB_Byte, than I removed the complete procedure
and replaced the call with PeekA().
Later I thought I should provide the 'original' code and copied the procedure back in the code.

Sh.. happens.
Now I commented it out, because it is not needed.
Best regards,
Bernd
Re: sha1 fingerprint string
Posted: Tue May 18, 2010 1:48 pm
by infratec
@eddy
maybe something with the attachment of a 1 bit and padding with 0 is wrong/missing.
And why did you do this
It is faster and easier to use
Bernd