|
Author
|
Topic: TEA (To Peter Redei)
|
Torsten Rienow Member
|
posted March 17, 2002 09:41 AM
Peter,you can easy build an outer loop. v and w are pointers to buffers. Add a parameter to the subs that will hold the buffersize. Regards, Torsten P.S.: i believe that Board Admins does not like discussion in SC Forum. P.P.S.: RTFM at http://vader.brad.ac.uk/tea/tea.shtml P.P.P.S.: If you cannot display .ps files then To read the documents please go to http://www.cs.wisc.edu/~ghost/doc/AFPL/get704.htm and download and install AFPL Ghostscript 7.04 for Win32 by following the Windows 95, 98, ME, NT, 2000 or XP section. After that download and install GSview 4.2 from the same site. Then start GSView and open the .ps documents to read them. The quality of the document opened with the software above is excellent. ------------------
[This message has been edited by Torsten Rienow (edited March 17, 2002).] IP: Logged |
Peter Redei Member
|
posted March 17, 2002 02:44 PM
Thank you Thorsten for your prompt answer. I could not get this documentation (it was not accessible), but I wrote something that seems to work based on your input:#COMPILE EXE #REGISTER NONE DECLARE FUNCTION TEA_Decode(BYVAL sCoded AS STRING, k AS STRING * 16) AS STRING DECLARE FUNCTION TEA_Encode(BYVAL sText AS STRING, k AS STRING * 16) AS STRING FUNCTION PBMAIN DIM keyWord AS STRING * 16 DIM sText AS STRING DIM sCoded AS STRING DIM sDecoded AS STRING sText = "Dear PowerBasic users," & $CRLF & "TEA is working with PB very well." sCoded = TEA_Encode(sText, keyWord) sDecoded = TEA_Decode(sCoded, keyWord) MSGBOX sDecoded, 0, "Inline Assembler" END FUNCTION FUNCTION TEA_Decode(BYVAL sCoded AS STRING, k AS STRING * 16) AS STRING DIM v AS STRING * 8 DIM w AS STRING * 8 DIM sDecoded AS STRING DIM i AS LONG sDecoded = "" FOR i = 1 TO LEN(sCoded) \ 8 v = MID$(sCoded, (i - 1) * 8 + 1, 8) CALL decipherASM(BYVAL VARPTR(v), BYVAL VARPTR(w), BYVAL VARPTR(k), 32) sDecoded = sDecoded & w NEXT IF LEN(sCoded) MOD 8 > 0 THEN 'the leftover v = RIGHT$(sCoded, LEN(sCoded) MOD 8) CALL encipherASM(BYVAL VARPTR(v), BYVAL VARPTR(w), BYVAL VARPTR(k), 32) sDecoded = sDecoded & w END IF FUNCTION = sDecoded END FUNCTION FUNCTION TEA_Encode(BYVAL sText AS STRING, k AS STRING * 16) AS STRING DIM v AS STRING * 8 DIM w AS STRING * 8 DIM sCoded AS STRING DIM i AS LONG 'Test Inline Asm Version sCoded = "" FOR i = 1 TO LEN(sText)\8 v = MID$(sText, (i - 1) * 8 + 1, 8) CALL encipherASM(BYVAL VARPTR(v), BYVAL VARPTR(w), BYVAL VARPTR(k), 32) sCoded = sCoded & w NEXT IF LEN(sText) MOD 8 > 0 THEN 'the leftover v = RIGHT$(sText, LEN(sText) MOD 8) CALL encipherASM(BYVAL VARPTR(v), BYVAL VARPTR(w), BYVAL VARPTR(k), 32) sCoded = sCoded & w END IF FUNCTION = sCoded END FUNCTION FUNCTION encipherASM(BYVAL v AS DWORD PTR, BYVAL w AS DWORD PTR, BYVAL k AS DWORD PTR, BYVAL nLoops AS LONG) AS DWORD DIM y AS DWORD DIM z AS DWORD y = @v[0] z = @v[1] !MOV EDI, nLoops !MOV EDX, k !MOV EAX, z !MOV ESI, 0 eLoop: !MOV EBX, EAX !SHL EAX, 4 !SHR EBX, 5 !XOR EAX, EBX !ADD EAX, z !MOV ECX, ESI !AND ECX, 3 !MOV ECX, [EDX + ECX * 4] !ADD ECX, ESI !XOR EAX, ECX !ADD EAX, y !MOV y, EAX !ADD ESI, &H9E3779B9??? !MOV EBX, EAX !SHL EAX, 4 !SHR EBX, 5 !XOR EAX, EBX !ADD EAX, y !MOV ECX, ESI !SHR ECX, 11 !AND ECX, 3 !MOV ECX, [EDX + ECX * 4] !ADD ECX, ESI !XOR EAX, ECX !ADD EAX, z !MOV z, EAX !DEC EDI !JNZ eLoop @w[0] = y @w[1] = z END FUNCTION SUB decipherASM(BYVAL v AS DWORD PTR, BYVAL w AS DWORD PTR, BYVAL k AS DWORD PTR, BYVAL nLoops AS LONG) DIM y AS DWORD DIM z AS DWORD y = @v[0] z = @v[1] !MOV EDI, nLoops !MOV EAX, &H9E3779B9??? !MUL EDI !MOV ESI, EAX !MOV EDX, k !MOV EBX, y eLoop: !MOV EAX, EBX !SHL EAX, 4 !SHR EBX, 5 !XOR EAX, EBX !ADD EAX, y !MOV ECX, ESI !SHR ECX, 11 !AND ECX, 3 !MOV ECX, [EDX + ECX * 4] !ADD ECX, ESI !XOR EAX, ECX !MOV EBX, z !SUB EBX, EAX !MOV z, EBX !SUB ESI, &H9E3779B9??? !MOV EAX, EBX !SHL EAX, 4 !SHR EBX, 5 !XOR EAX, EBX !ADD EAX, z !MOV ECX, ESI !AND ECX, 3 !MOV ECX, [EDX + ECX * 4] !ADD ECX, ESI !XOR EAX, ECX !MOV EBX, y !SUB EBX, EAX !MOV y, EBX !DEC EDI !JNZ eLoop @w[0] = y @w[1] = z END SUB Regards, Peter Redei ------------------
IP: Logged |
Torsten Rienow Member
|
posted March 17, 2002 03:46 PM
Peter,I would suggest to put the "outer loop" inside the enc/dec functions. This could easy be done in PB Basic Version and PB Inline ASM version. You are free to modify my code anyway you like. If you have to crypt/decrypt large buffers calling overhead is significant. To read the documents on vader right click on the link and "save as" Then you should install Ghostview as decribed above. Regards, Torsten
------------------
IP: Logged |
Peter Redei Member
|
posted March 17, 2002 04:59 PM
Hi Torsten, I tried to run this code in PBDLL 6.0 and it did not work. Using v.6.11 it works fine. Using the PBDLL code instead of the ASM results in the same. What am I missing here?Regards, Peter Redei ------------------
IP: Logged |
Peter Lameijn Member
|
posted March 18, 2002 01:20 AM
Seems that PBDll 6.0 doesn't like duplicate asm labels (although they are in different subs). Renaming one of the eloop: labels solves it.... ------------------ Peter. peterL@pabx-group.com IP: Logged |
Torsten Rienow Member
|
posted March 18, 2002 01:59 AM
Peter, Peter,PBDLL 6.0 does have problems with ASM labels and !jmp. In PBDLL 6.0 !JMP <label> goes to the first <label> it can find in the entire app. This may be a <label> with the same name in an other procedure. PBDLL 6.0 does not compile <byval var as type PTR>. Instead you must use <byref var as type>. Regards, Torsten ------------------
IP: Logged |
Torsten Rienow Member
|
posted March 21, 2002 06:31 AM
Paul,your version of TEA is the first version. On brader is a link to "TEA new Variant" that corrects some minor weaknesses. This version i have implemented. To verify my code i have made the c++ dll below. The results from encipher/decipher of all versions, PBASIC , PBASIC INLINE and C++ are the same, so for me the code is verified. The difference between C++ and BASIC is that i have made the count of rounds variable by "n" to "nLoops" as function paramter. regards, Torsten
#include "stdafx.h" BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { return TRUE; }__declspec(dllexport) unsigned long encipher(const unsigned long *const v,unsigned long *const w, const unsigned long * const k) { register unsigned long y=v[0],z=v[1],sum=0,delta=0x9E3779B9,n=1; while(n-->0) { y += (z << 4 ^ z >> 5) + z ^ sum + k[sum&3]; sum += delta; z += (y << 4 ^ y >> 5) + y ^ sum + k[sum>>11 & 3]; } w[0]=y; w[1]=z; return (z); } __declspec(dllexport) decipher(const unsigned long *const v,unsigned long *const w, const unsigned long * const k) { register unsigned long y=v[0],z=v[1],sum=0xC6EF3720, delta=0x9E3779B9,n=1; /* sum = delta<<5, in general sum = delta * n */ while(n-->0) { z -= (y << 4 ^ y >> 5) + y ^ sum + k[sum>>11 & 3]; sum -= delta; y -= (z << 4 ^ z >> 5) + z ^ sum + k[sum&3]; } w[0]=y; w[1]=z; }
------------------
[This message has been edited by Torsten Rienow (edited March 21, 2002).] IP: Logged |
Paul Dwyer Member
|
posted March 21, 2002 06:38 AM
Thanks, I'll take a look at that ver too, I just posted an update of my version to fix a couple of bugs though I have added the use of abirtrary string lengths as I had problems modifying your code and having it still work (it was fine if I left it alone though :-( ) (ADDED) I just found a major bug with the way I was handling the key effectively cutting the keyspace in half, This has been fixed #Compile Exe
Union DWordBytes DW As Dword B(1 To 4) As Byte End Union Declare Sub TeaEncrypt(sData As String, Key As String, ByVal nLoops As Long) Declare Sub TeaDecrypt(sData As String, Key As String, ByVal nLoops As Long) Function PbMain() As Long Dim sInput As String Dim hexKey As String: HexKey = "123456789ABCDEF0123456789ABCDEF0" Dim nLoops As Long: Nloops = 32 sInput = InputBox$("Input Text to be encrypted", "Tea Coder") MsgBox "Input = " & sInput Call TeaEncrypt(sInput, hexKey, nLoops) MsgBox "Enc Output = " & Sinput HexKey = "123456789ABCDEF0123456789ABCDEF0" Call TeaDecrypt(sinput, hexKey, nLoops) MsgBox "Dec Output = " & sinput End Function Sub TeaEncrypt(sData As String, Key As String, ByVal nLoops As Long) Dim Delta As Dword: Delta = &h9E3779B9 Dim Sum As Dword: Sum = &hC6EF3720 Dim Y As DWordBytes, Y1 As DWordBytes, Y2 As DWordBytes Dim Z As DWordBytes, Z1 As DWordBytes, Z2 As DWordBytes Dim a As Dword, b As Dword Dim c As Dword, d As Dword Dim DataLen As Long: DataLen = Len(sData) Dim iEnc As Long ' 64bit enc Loop var Dim BytePasser As Long ' Pass Bytes to Enc Loop Dim Bytes(1 To Datalen) As Byte At StrPtr(sData)
' Prep Key a = Val("&H" & Mid$(key, 1,8)) b = Val("&H" & Mid$(key, 9,8)) c = Val("&H" & Mid$(key, 17,8)) d = Val("&H" & Mid$(key, 25,8)) ' Pass Bytes through to Enc Loop For BytePasser = 1 To DataLen Step 8 Y.B(1) = Bytes(BytePasser) Y.B(2) = Bytes(BytePasser +1) Y.B(3) = Bytes(BytePasser +2) Y.B(4) = Bytes(BytePasser +3) Z.B(1) = Bytes(BytePasser+4) Z.B(2) = Bytes(BytePasser+5) Z.B(3) = Bytes(BytePasser+6) Z.B(4) = Bytes(BytePasser+7) Sum = &h0 For iEnc = 1 To nloops sum = sum + delta Z1.dw = Z.dw Z2.dw = Z.dw Shift Left z1.dw, 4 Shift Right z2.dw, 5 Y.dw = Y.dw + (Z1.dw + a Xor Z.dw + sum Xor Z2.dw + b) Y1.dw = Y.dw Y2.dw = Y.dw Shift Left y1.dw, 4 Shift Right y2.dw, 5 Z.dw = Z.dw + (Y1.dw + c Xor Y.dw + sum Xor Y2.dw + d) Next Bytes(BytePasser) = Y.B(1) Bytes(BytePasser +1) = Y.B(2) Bytes(BytePasser +2) = Y.B(3) Bytes(BytePasser +3) = Y.B(4) Bytes(BytePasser+4) = Z.B(1) Bytes(BytePasser+5) = Z.B(2) Bytes(BytePasser+6) = Z.B(3) Bytes(BytePasser+7) = Z.B(4) Next End Sub Sub TeaDecrypt(sData As String, Key As String, ByVal nLoops As Long)
Dim Delta As Dword: Delta = &h9E3779B9 Dim Sum As Dword: Sum = &hC6EF3720 Dim Y As DWordBytes, Y1 As DWordBytes, Y2 As DWordBytes Dim Z As DWordBytes, Z1 As DWordBytes, Z2 As DWordBytes Dim a As Dword, b As Dword Dim c As Dword, d As Dword Dim DataLen As Long: DataLen = Len(sData) Dim iEnc As Long ' 64bit enc Loop var Dim BytePasser As Long ' Pass Bytes to Enc Loop Dim Bytes(1 To Datalen) As Byte At StrPtr(sData)
' Prep Key a = Val("&H" & Mid$(key, 1,8)) b = Val("&H" & Mid$(key, 9,8)) c = Val("&H" & Mid$(key, 17,8)) d = Val("&H" & Mid$(key, 25,8)) ' Pass Bytes through to Enc Loop For BytePasser = 1 To DataLen Step 8 Y.B(1) = Bytes(BytePasser) Y.B(2) = Bytes(BytePasser +1) Y.B(3) = Bytes(BytePasser +2) Y.B(4) = Bytes(BytePasser +3) Z.B(1) = Bytes(BytePasser+4) Z.B(2) = Bytes(BytePasser+5) Z.B(3) = Bytes(BytePasser+6) Z.B(4) = Bytes(BytePasser+7) Sum = &hC6EF3720 For iEnc = 1 To nloops Y1.dw = Y.dw Y2.dw = Y.dw Shift Left y1.dw, 4 Shift Right y2.dw, 5 Z.dw = Z.dw - (Y1.dw + c Xor y.dw + sum Xor y2.dw + d) Z1.dw = Z.dw Z2.dw = Z.dw Shift Left z1.dw, 4 Shift Right z2.dw, 5 y.dw = y.dw - (z1.dw + a Xor z.dw + sum Xor Z2.dw + b) sum = sum - delta Next Bytes(BytePasser) = Y.B(1) Bytes(BytePasser +1) = Y.B(2) Bytes(BytePasser +2) = Y.B(3) Bytes(BytePasser +3) = Y.B(4) Bytes(BytePasser+4) = Z.B(1) Bytes(BytePasser+5) = Z.B(2) Bytes(BytePasser+6) = Z.B(3) Bytes(BytePasser+7) = Z.B(4) Next
End Sub
[This message has been edited by Paul Dwyer (edited March 22, 2002).] IP: Logged |
George Bleck Member
|
posted September 28, 2003 08:29 PM
Found a weird result...If you use the following string to encode: WW1234567890123456789012345678901234567890 it decodes back to a different string The weird thing is it doesn't do it everytime...  It's very hard to determine why...I tested it on a WinXP sp1 box and a Win2k Server sp4 box use code compiled verbatim from the above posting. The problem appears most prevalent when I use the above string and do cut and paste in the inputbox.
------------------ Every day I try to learn one thing new, but new things to learn are increasing exponentially. At this rate I’m becoming an idiot faster and faster !!! ------------------ George W. Bleck Lead Computer Systems Engineer KeySpan Corporation My Email IP: Logged |
Torsten Rienow Member
|
posted September 29, 2003 01:25 AM
George,are you sure that your input string is always with or without crlf at the end? regards, Torsten ------------------
IP: Logged |
George Bleck Member
|
posted September 29, 2003 02:06 PM
Good question...I added the following code right after sInput = InputBox$("Input Text to be encrypted", "Tea Coder")
KILL "binary.dat" OPEN "binary.dat" FOR BINARY AS #1 PUT$ #1, sInput CLOSE #1
The binary.dat file was 42 bytes long and was exactly what I had pasted (no more, no less) and yet the decrypted text was wrong. ------------------ Every day I try to learn one thing new, but new things to learn are increasing exponentially. At this rate I’m becoming an idiot faster and faster !!! ------------------ George W. Bleck Lead Computer Systems Engineer KeySpan Corporation My Email [This message has been edited by George Bleck (edited September 29, 2003).] IP: Logged |
George Bleck Member
|
posted September 30, 2003 08:48 PM
Here is a modified version using Torsten's ASM version from the SC forum. Sorry it's not all in Assembly... haven't done ASM in years  Comments welcome. 'HEXTEA.BAS ' 'Original by Torsten Rienow ' 'Modified by George Bleck ' 'Additions: ' Allows variable length strings ' Converts the encoded text to hex for use in standard text files ' 'Drawbacks ' If the original text ends in CHR$(0)'s they get lost on the decode'----------------------------------------------------------------------------(') #COMPILE EXE #REGISTER NONE '----------------------------------------------------------------------------(') FUNCTION TEA_ASM_Encode( BYVAL pstrInputBuffer AS DWORD PTR, BYVAL lngStrLen AS LONG, BYVAL pstrOutputBuffer AS DWORD PTR, BYVAL pstrKey AS DWORD PTR, BYVAL lngLoopCount AS LONG ) AS DWORD LOCAL y AS DWORD LOCAL z AS DWORD LOCAL lngIndex AS LONG FOR lngIndex = 0 TO (( lngStrLen / 4 ) - 1 ) STEP 2 y = @pstrInputBuffer [ lngIndex ] z = @pstrInputBuffer [ lngIndex + 1 ] !MOV EDI, lngLoopCount !MOV EDX, pstrKey !MOV EAX, z !MOV ESI, 0 TEA_ASM_EncodeLoop : !MOV EBX, EAX !SHL EAX, 4 !SHR EBX, 5 !XOR EAX, EBX !ADD EAX, z !MOV ECX, ESI !AND ECX, 3 !MOV ECX, [EDX + ECX * 4] !ADD ECX, ESI !XOR EAX, ECX !ADD EAX, y !MOV y, EAX !ADD ESI, &H9E3779B9??? !MOV EBX, EAX !SHL EAX, 4 !SHR EBX, 5 !XOR EAX, EBX !ADD EAX, y !MOV ECX, ESI !SHR ECX, 11 !AND ECX, 3 !MOV ECX, [EDX + ECX * 4] !ADD ECX, ESI !XOR EAX, ECX !ADD EAX, z !MOV z, EAX !DEC EDI !JNZ TEA_ASM_EncodeLoop @pstrOutputBuffer [ lngIndex ] = y @pstrOutputBuffer [ lngIndex + 1 ] = z NEXT lngIndex END FUNCTION '----------------------------------------------------------------------------(') SUB TEA_ASM_Decode( BYVAL pstrInputBuffer AS DWORD PTR, BYVAL lngStrLen AS LONG, BYVAL pstrOutputBuffer AS DWORD PTR, BYVAL pstrKey AS DWORD PTR, BYVAL lngLoopCount AS LONG ) LOCAL y AS DWORD LOCAL z AS DWORD LOCAL lngIndex AS LONG FOR lngIndex = 0 TO (( lngStrLen / 4 ) - 1 ) STEP 2 y = @pstrInputBuffer [ lngIndex ] z = @pstrInputBuffer [ lngIndex + 1 ] !MOV EDI, lngLoopCount !MOV EAX, &H9E3779B9??? !MUL EDI !MOV ESI, EAX !MOV EDX, pstrKey !MOV EBX, y TEA_ASM_DecodeLoop : !MOV EAX, EBX !SHL EAX, 4 !SHR EBX, 5 !XOR EAX, EBX !ADD EAX, y !MOV ECX, ESI !SHR ECX, 11 !AND ECX, 3 !MOV ECX, [EDX + ECX * 4] !ADD ECX, ESI !XOR EAX, ECX !MOV EBX, z !SUB EBX, EAX !MOV z, EBX !SUB ESI, &H9E3779B9??? !MOV EAX, EBX !SHL EAX, 4 !SHR EBX, 5 !XOR EAX, EBX !ADD EAX, z !MOV ECX, ESI !AND ECX, 3 !MOV ECX, [EDX + ECX * 4] !ADD ECX, ESI !XOR EAX, ECX !MOV EBX, y !SUB EBX, EAX !MOV y, EBX !DEC EDI !JNZ TEA_ASM_DecodeLoop @pstrOutputBuffer [ lngIndex ] = y @pstrOutputBuffer [ lngIndex + 1 ] = z NEXT lngIndex END SUB '----------------------------------------------------------------------------(') FUNCTION TEA_Encode( strTextToEncode AS STRING, strKey AS STRING ) AS STRING LOCAL strInputBuffer AS STRING LOCAL strOutputBuffer AS STRING LOCAL strTemp AS STRING strInputBuffer = strTextToEncode & STRING$( 8 - ( LEN( strTextToEncode ) MOD 8 ), CHR$( 0 )) strOutputBuffer = SPACE$( LEN( strInputBuffer )) CALL TEA_ASM_Encode( BYVAL STRPTR( strInputBuffer ), BYVAL LEN( strInputBuffer ), BYVAL STRPTR( strOutputBuffer ), BYVAL STRPTR( strKey ), 256 ) strTemp = "" FOR t& = 1 TO LEN( strOutputBuffer ) strTemp = strTemp & HEX$( ASC( strOutputBuffer, t& ), 2 ) NEXT t& FUNCTION = strTemp END FUNCTION '----------------------------------------------------------------------------(') FUNCTION TEA_Decode( strTextToDecode AS STRING, strKey AS STRING ) AS STRING LOCAL strInputBuffer AS STRING LOCAL strOutputBuffer AS STRING FOR t& = 1 TO LEN( strTextToDecode ) STEP 2 strInputBuffer = strInputBuffer & CHR$(VAL("&H" & MID$(strTextToDecode,t&,2))) NEXT t& strOutputBuffer = SPACE$( LEN( strInputBuffer )) CALL TEA_ASM_Decode( BYVAL STRPTR( strInputBuffer ), BYVAL LEN( strInputBuffer ), BYVAL STRPTR( strOutputBuffer ), BYVAL STRPTR( strKey ), 256 ) FUNCTION = EXTRACT$(strOutputBuffer,CHR$(0)) END FUNCTION '----------------------------------------------------------------------------(') FUNCTION PBMAIN( ) LOCAL strInputBuffer AS STRING LOCAL strKey AS STRING LOCAL strEncodedHex AS STRING LOCAL strDecodedHex AS STRING strKey = CHR$( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6 ) strInputBuffer = InputBox$("Input Text to be encrypted", "Tea Coder") strEncodedHex = TEA_Encode( strInputBuffer, strKey ) strDecodedHex = TEA_Decode(strEncodedHex, strKey) MSGBOX _ "You entered" & $CR & _ strInputBuffer & $CR & $CR & _ "Encoded and converted to hex it becomes" & $CR & _ strEncodedHex & $CR & $CR & _ "Decoded it becomes" & $CR & _ strDecodedHex END FUNCTION
------------------ Every day I try to learn one thing new, but new things to learn are increasing exponentially. At this rate I’m becoming an idiot faster and faster !!! ------------------ George W. Bleck Lead Computer Systems Engineer KeySpan Corporation My Email [This message has been edited by George Bleck (edited September 30, 2003).] IP: Logged |
Michael Ritter Member
|
posted October 01, 2003 12:55 PM
Peter,If your encoding a large amount of data you might check out the mmx version of tea that I ported. I am interested for people to test my port to help find issues. http://www.powerbasic.com/support/forums/Forum7/HTML/001617.html Cheers, Michael ------------------
IP: Logged |