Code:
'Power Basic version of 'The RC6(TM) Block Cipher 'Ronald L. Rivest1, M.J.B. Robshaw2, R. Sidney2, and Y.L. Yin2 ' M.I.T. Laboratory for Computer Science, 545 Technology Square, Cambridge, 'MA 02139, USA '[email protected] ' RSA Laboratories, 2955 Campus Drive, Suite 400, San Mateo, CA 94403, USA 'fmatt,ray,[email protected] 'Version 1.1 - August 20, 1998 '------------------------------ ' 'Writen at 11/3/2007 by Aleksandr Dobrev from scratch based on original material: 'http://www.rsa.com/rsalabs/node.asp?id=2512 'ftp://ftp.rsasecurity.com/pub/rsalabs/rc6/rc6v11.pdf 'http://people.csail.mit.edu/rivest/publications.html 'http://people.csail.mit.edu/rivest/ContiniRivestRobshawYin-ImprovedAnalysisOfSomeSimplifiedVariantsOfRC6.pdf ' 'Version 1.0: 'This is a base version which accept source material for encryption as block of memory = 16 bytes 'User key(password) can be in range from 0-255 bytes(current version accept lenght of the key multiplied by 4 only (0,4,8,16,...255) 'source code below contain three base subrotine of RC6 'MakeRC6key - compute RC6 Key Schedule 'Rc6Encrypt16bytesBlock - source code for encryption in plain PowerBasic version 'Rc6Encrypt16bytesBlockASM - source code for encryption in plain assembler(should be faster) version 'Rc6Decrypt16bytesBlock - source code for decryption in plain PowerBasic 'fx() - additional function which resolve issue of PowerBasic in computation on integer multiplication ' 'rest of the code is testing algorithms by official test vectors '========================================================================================================== ' #COMPILER PBWIN ' 8.04 #COMPILE EXE #DIM ALL ' DECLARE SUB jCopyMemory LIB "KERNEL32.DLL" ALIAS "RtlMoveMemory" (BYVAL pDestination AS BYTE PTR, BYVAL pSource AS BYTE PTR, BYVAL cbLength AS LONG) '=================== $ResultFile = "Rc6test.txt" '%SaveKeySchedule = 1 ' UnRem it if you want save KeySchedule array %NumberOfTestVectors = 5 ' Zero base (6 test vectors) '=================== '////////////////////////// RC6 algorithm specific constatnts ///////////////////////////// 'The "magic constants" for RC6 with 32-bit wordsize 'The constants P32 = B7E15163 and Q32 = 9E3779B9 (hexadecimal) are the 'same "magic constants" as used in the RC5 key schedule. The value of P32 is 'derived from the binary expansion of e -2, where e is the base of the natural 'logarithm function. The value of Q32 is derived from the binary expansion of '[/] - 1, where [/] is the Golden Ratio. Similar definitions from RC5 for P64 etc. can 'be used for versions of RC6 with other word sizes. These values are somewhat 'arbitrary, and other values could be chosen to give "custom" or proprietary 'versions of RC6. '-------------------- ' %P32 = &hB7E15163??? ' default value = &hB7E15163???, can be changed for proprietary version of RC6. Can't be zero %Q32 = &h9E3779B9??? ' default value = &h9E3779B9???, can be changed for proprietary version of RC6. Can't be zero '-------------------- ' %KeyScheduleROUNDS = 3 ' default value = 3, can be changed for proprietary version of RC6, recommended no less than 3 '-------------------- 'This #define is specific to RC6: the number of rounds of encipherment ' %ROUNDS = 20 ' default value = 20, can be changed for proprietary version of RC6, recommended no less than 20 ' Then bigger, than slower but more strong encryprtion and vise versa 'You can customize you RC6 algorithm by changing number of rounds, but keep in mind, 'what authors of algorithms don't recommend number of rounds below 20 'here tables of crypto analisis for defferential and linear attacks ' Differential Cryptanalysis of RC6 '----------------------------------------------------------- ' | number of rounds '----------------------------------------------------------- 'variant 8 12 16 20 24 '----------------------------------------------------------- 'RC6 2^93 2^151 2^214 2^279 2^337 'iterative 'characteristic ' ' 'RC6 2^91 2^147 2^210 2^273 2^329 'iterative 'differential ' ' 'RC6 2^56 2^117 2^190 2^238 2^299 'using 'customized 'differentials '----------------------------------------------------------- '*********************************************************** 'Using Type I Approximations '----------------------------------------------------------- ' number of rounds '----------------------------------------------------------- ' variant 8 12 16 20 24 '----------------------------------------------------------- 'RC6 2^62 2^102 2^142 2^182 2^222 'basic linear attack ' 'RC6 2^51 2^91 2^131 2^171 2^211 '+ multiple approximations ' 'RC6 2^47 2^83 2^119 2^155 2^191 '+ multiple approximations '+ linear hulls '////////////////////////////////////////////////////////////////////////////////////////// ' ' ' ' ' ' ' ' ' ' ' '////////////////////////////////////////////////////////////////////////////////////////// '-------------------------------------------------------------------------------------------------------------- 'SUB MakeRC6Key 'Purpose: compute RC6 Key Schedule '[IN] Key - byte pointer to source Password '[IN] keyLengthInBytes - lenght of Password in bytes '[OUT] S - pointer to DWORD array where RC6 Key Schedule will be stored '-------------------------------------------------------------------------------------------------------------- SUB MakeRC6Key(BYVAL key AS BYTE PTR, BYVAL keyLengthInBytes AS LONG, BYVAL S AS DWORD PTR) LOCAL arrL AS STRING LOCAL L AS DWORD PTR LOCAL A, B, c, i, j, v, x, z AS DWORD ' z = (2*%ROUNDS + 4) arrL = REPEAT$(keyLengthInBytes,CHR$(0)) L = STRPTR(arrL) ' jCopyMemory(BYVAL L, BYVAL key, BYVAL keyLengthInBytes) ' @S[0] = %P32 FOR i = 1 TO (z -1) @S[i] = @S[i-1] + %Q32 NEXT ' A = 0: B = 0: i = 0: j = 0 c = keyLengthInBytes/4 v = %KeyScheduleROUNDS * MAX(c, z) ' FOR x = 1 TO v @S[i] = @S[i] + A + B ROTATE LEFT @S[i], 3 : A = @S[i] ' @L[j] = @L[j] + A + B ROTATE LEFT @L[j], (A + B) : B = @L[j] ' INCR i : IF (i = z) THEN i = 0 INCR j : IF (j = c) THEN j = 0 NEXT END SUB ' ' '-------------------------------------------------------------------------------------------------------------- 'Function fx 'Purpose : PowerBasic can't calculate B*(2*B+1) correctly as it work in all other compilers ' So, we should do it by ourself '[IN] dwIn - Source Y '[RETURN] - dwIn * (dwIn * 2 + 1) '-------------------------------------------------------------------------------------------------------------- FUNCTION fx(BYVAL dwIn AS DWORD) AS DWORD #REGISTER NONE ! mov eax, dwIn ! shl eax , 1 ; b*2 ! inc eax ; b*2+1 ! mul dwIn ; b*(b*2+1) ! mov function, eax END FUNCTION ' '-------------------------------------------------------------------------------------------------------------- 'SUB Rc6Encrypt16bytesBlock '[IN] S - pointer to RC6 Key Schedule array of DWORD '[IN] plaintext - pointer to 16 bytes block Source material '[OUT]ciphertext- pointer to 16 bytes block Where will be stored ecrypted data '-------------------------------------------------------------------------------------------------------------- SUB Rc6Encrypt16bytesBlock(BYVAL S AS DWORD PTR, BYVAL plaintext AS DWORD PTR, BYVAL ciphertext AS DWORD PTR ) LOCAL A,B,C,D, Bx,Dx, i AS DWORD '*** Load A, B, C, and D registers from plaintext *** A = @plaintext[0] B = @plaintext[1] C = @plaintext[2] D = @plaintext[3] '*** Do pseudo-round #0: pre-whitening of B and D *** B = B + @S[0] D = D + @S[1] '*** Perform round #1, #2, ..., #ROUNDS of encryption *** FOR i = 1 TO %ROUNDS ' Bx = fx(B) 'B*(2*B+1) ROTATE LEFT Bx, 5 ' Dx = fx(D) 'D*(2*D+1) ROTATE LEFT Dx, 5 ' A = (A XOR Bx) ROTATE LEFT A, (Dx AND &h1f???) A = A + @S[2*i] ' C = (C XOR Dx) ROTATE LEFT C, (Bx AND &h1f???) C = C + @S[2*i+1] ' ! push A 'temp = A ' ! push B 'A = B ! pop A ! push C 'B = C ! pop B ! push D 'C = D ! pop C ! pop D 'D = temp ' NEXT '*** Do pseudo-round #(ROUNDS+1): post-whitening of A and C *** A = A + @S[2*%ROUNDS+2] C = C + @S[2*%ROUNDS+3] '*** Store A, B, C, and D registers to ciphertext *** @ciphertext[0] = A @ciphertext[1] = B @ciphertext[2] = C @ciphertext[3] = D END SUB '-------------------------------------------------------------------------------------------------------------- 'SUB Rc6Encrypt16bytesBlockASM 'Purpose : Encrypt 16 bytes block of source material by RC6 '[IN] S - pointer to RC6 Key Schedule array of DWORD '[IN] plaintext - pointer to 16 bytes block Source material '[OUT]ciphertext- pointer to 16 bytes block Where will be stored ecrypted data '-------------------------------------------------------------------------------------------------------------- SUB Rc6Encrypt16bytesBlockASM(BYVAL S AS DWORD PTR, BYVAL plaintext AS DWORD PTR, BYVAL ciphertext AS DWORD PTR ) LOCAL A,B,C,D AS DWORD #REGISTER NONE ! mov esi, plaintext ; pointer to Source material for encryption ' Load A, B, C, and D registers from plaintext ! mov edx, dword ptr[esi] 'A = @plaintext[0] ! mov ecx, dword ptr[esi+4] 'B = @plaintext[1] ! mov ebx, dword ptr[esi+8] 'C = @plaintext[2] ! mov eax, dword ptr[esi+12] 'D = @plaintext[3] ! mov A, edx ! mov B, ecx ! mov C, ebx ! mov D, eax '/* Do pseudo-round #0: pre-whitening of B and D */ ! mov esi, S ;=== pointer to key schedule ' ! add eax,dword ptr [esi+4] 'D = D + @S[1] ! mov D, eax ' ! mov eax, B ! add eax, dword ptr [esi] 'B = B + @S[0] ! mov B, eax '/* Perform round #1, #2, ..., #ROUNDS of encryption */ ! xor edi, edi Loop1: ! inc edi ! cmp edi, %ROUNDS ! JA Next1 'FOR i = 1 TO %ROUNDS ! mov eax, B 'Bxx = B*(2*B+1) ! shl eax , 1 ; b*2 ! inc eax ; b*2+1 ! mul B ; b*(b*2+1) ! rol eax,5 'ROTATE LEFT Bxx, 5 ! mov ebx, eax ; Save Bxx in EBX ' ! mov eax, D 'Dxx = D*(2*D+1) ! shl eax , 1 ! inc eax ! mul D ! rol eax,5 'ROTATE LEFT Dxx, 5 ! mov edx, eax ' !mov eax, A 'A = (A XOR Bxx) !xor eax, ebx !mov ecx, edx 'ROTATE LEFT A, (Dxx AND &h1f???) !rol eax, cl !add eax, [esi+edi*8] 'A = A + @S[2*i] !mov A, EAX ' !mov eax, C 'C = (C XOR Dxx) !xor eax, edx !mov ecx, ebx 'ROTATE LEFT C, (Bxx AND &h1f???) !rol eax, cl !add eax, [esi+edi*8+4] 'C = C + @S[2*i+1] !mov C, EAX ' ! push A 'temp = A ' ! push B 'A = B ! pop A ! push C 'B = C ! pop B ! push D 'C = D ! pop C ! pop D 'D = temp ' ' NEXT !jmp loop1 Next1: '/* Do pseudo-round #(ROUNDS+1): post-whitening of A and C */ ! mov edx, %ROUNDS ' ! mov eax, C 'C = C + @S[2*%ROUNDS+3] ! add eax, [esi+edx*8+12] ! mov C, eax ' ! mov eax, A 'A = A + @S[2*%ROUNDS+2] ! add eax, [esi+edx*8+8] '/* Store A, B, C, and D registers to ciphertext */ ! mov edi, ciphertext ' ! mov ebx, B ! mov ecx, C ! mov edx, D ! mov [edi], eax ' @ciphertext[0] = A ! mov [edi+4], ebx ' @ciphertext[1] = B ! mov [edi+8], ecx ' @ciphertext[2] = C ! mov [edi+12],edx ' @ciphertext[3] = D END SUB '-------------------------------------------------------------------------------------------------------------- 'SUB Rc6Decrypt16bytesBlock 'Purpose : Decrypts a single 16-bytes block of cipher. '[IN] S - pointer to RC6 Key Schedule array of DWORD '[IN] ciphertext - pointer to 16 bytes cypher block '[OUT]plaintext - pointer to 16 bytes block Where will be stored derypted data '-------------------------------------------------------------------------------------------------------------- SUB Rc6Decrypt16bytesBlock(BYVAL S AS DWORD PTR, BYVAL ciphertext AS DWORD PTR, BYVAL plaintext AS DWORD PTR) LOCAL i AS LONG LOCAL A,B,C,D, t, u, temp AS DWORD '*** Load A, B, C, and D registers from ciphertext *** A = @ciphertext[0] B = @ciphertext[1] C = @ciphertext[2] D = @ciphertext[3] '*** Undo pseudo-round #(ROUNDS+1): post-whitening of A and C *** C = C - @S[2*%ROUNDS+3] A = A - @S[2*%ROUNDS+2] '*** Undo round #ROUNDS, ..., #2, #1 of encryption *** i = %ROUNDS WHILE i >= 1 ! push D 'temp = D ! push C 'D = C ! pop D ! push B 'C = B ! pop C ! push A 'B = A ! pop B ! pop A 'A = temp ' t = fx(B) 'B*(2*B+1) ROTATE LEFT t, 5 ' u = fx(D) 'D*(2*D+1) ROTATE LEFT u, 5 ' C = C - @S[2*i+1] ROTATE RIGHT C, t C = C XOR u ' A = A - @S[2*i] ROTATE RIGHT A, u A = A XOR t ' DECR i WEND '*** Undo pseudo-round #0: pre-whitening of B and D *** D = D - @S[1] 'D -= S[1]; B = B - @S[0] 'B -= S[0]; '*** Store A, B, C, and D registers to plaintext *** @plaintext[0] = A @plaintext[1] = B @plaintext[2] = C @plaintext[3] = D END SUB '////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ' ' ' ' ' SUB FillTestVectors(plaintext() AS STRING, UserKey() AS STRING, ciphertext() AS STRING) 'Official Test vectors for encryption with RC6 ' plaintext(0) = CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00) userkey(0) = CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00) ciphertext(0)= CHR$(&H8f)+CHR$(&Hc3)+CHR$(&Ha5)+CHR$(&H36)+CHR$(&H56)+CHR$(&Hb1)+CHR$(&Hf7)+CHR$(&H78)+CHR$(&Hc1)+CHR$(&H29)+CHR$(&Hdf)+CHR$(&H4e)+CHR$(&H98)+CHR$(&H48)+CHR$(&Ha4)+CHR$(&H1e) ' plaintext(1)= CHR$(&H02)+CHR$(&H13)+CHR$(&H24)+CHR$(&H35)+CHR$(&H46)+CHR$(&H57)+CHR$(&H68)+CHR$(&H79)+CHR$(&H8a)+CHR$(&H9b)+CHR$(&Hac)+CHR$(&Hbd)+CHR$(&Hce)+CHR$(&Hdf)+CHR$(&He0)+CHR$(&Hf1) userkey(1)= CHR$(&H01)+CHR$(&H23)+CHR$(&H45)+CHR$(&H67)+CHR$(&H89)+CHR$(&Hab)+CHR$(&Hcd)+CHR$(&Hef)+CHR$(&H01)+CHR$(&H12)+CHR$(&H23)+CHR$(&H34)+CHR$(&H45)+CHR$(&H56)+CHR$(&H67)+CHR$(&H78) ciphertext(1)= CHR$(&H52)+CHR$(&H4e)+CHR$(&H19)+CHR$(&H2f)+CHR$(&H47)+CHR$(&H15)+CHR$(&Hc6)+CHR$(&H23)+CHR$(&H1f)+CHR$(&H51)+CHR$(&Hf6)+CHR$(&H36)+CHR$(&H7e)+CHR$(&Ha4)+CHR$(&H3f)+CHR$(&H18) ' plaintext(2)= CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00) userkey(2)= CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+_ CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00) ciphertext(2)= CHR$(&H6c)+CHR$(&Hd6)+CHR$(&H1b)+CHR$(&Hcb)+CHR$(&H19)+CHR$(&H0b)+CHR$(&H30)+CHR$(&H38)+CHR$(&H4e)+CHR$(&H8a)+CHR$(&H3f)+CHR$(&H16)+CHR$(&H86)+CHR$(&H90)+CHR$(&Hae)+CHR$(&H82) ' plaintext(3)= CHR$(&H02)+CHR$(&H13)+CHR$(&H24)+CHR$(&H35)+CHR$(&H46)+CHR$(&H57)+CHR$(&H68)+CHR$(&H79)+CHR$(&H8a)+CHR$(&H9b)+CHR$(&Hac)+CHR$(&Hbd)+CHR$(&Hce)+CHR$(&Hdf)+CHR$(&He0)+CHR$(&Hf1) userkey(3)= CHR$(&H01)+CHR$(&H23)+CHR$(&H45)+CHR$(&H67)+CHR$(&H89)+CHR$(&Hab)+CHR$(&Hcd)+CHR$(&Hef)+CHR$(&H01)+CHR$(&H12)+CHR$(&H23)+CHR$(&H34)+CHR$(&H45)+CHR$(&H56)+CHR$(&H67)+CHR$(&H78)+_ CHR$(&H89)+CHR$(&H9a)+CHR$(&Hab)+CHR$(&Hbc)+CHR$(&Hcd)+CHR$(&Hde)+CHR$(&Hef)+CHR$(&Hf0) ciphertext(3)= CHR$(&H68)+CHR$(&H83)+CHR$(&H29)+CHR$(&Hd0)+CHR$(&H19)+CHR$(&He5)+CHR$(&H05)+CHR$(&H04)+CHR$(&H1e)+CHR$(&H52)+CHR$(&He9)+CHR$(&H2a)+CHR$(&Hf9)+CHR$(&H52)+CHR$(&H91)+CHR$(&Hd4) ' plaintext(4)= CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00) userkey(4)= CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+_ CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00)+CHR$(&H00) ciphertext(4)= CHR$(&H8f)+CHR$(&H5f)+CHR$(&Hbd)+CHR$(&H05)+CHR$(&H10)+CHR$(&Hd1)+CHR$(&H5f)+CHR$(&Ha8)+CHR$(&H93)+CHR$(&Hfa)+CHR$(&H3f)+CHR$(&Hda)+CHR$(&H6e)+CHR$(&H85)+CHR$(&H7e)+CHR$(&Hc2) ' plaintext(5)= CHR$(&H02)+CHR$(&H13)+CHR$(&H24)+CHR$(&H35)+CHR$(&H46)+CHR$(&H57)+CHR$(&H68)+CHR$(&H79)+CHR$(&H8a)+CHR$(&H9b)+CHR$(&Hac)+CHR$(&Hbd)+CHR$(&Hce)+CHR$(&Hdf)+CHR$(&He0)+CHR$(&Hf1) userkey(5)= CHR$(&H01)+CHR$(&H23)+CHR$(&H45)+CHR$(&H67)+CHR$(&H89)+CHR$(&Hab)+CHR$(&Hcd)+CHR$(&Hef)+CHR$(&H01)+CHR$(&H12)+CHR$(&H23)+CHR$(&H34)+CHR$(&H45)+CHR$(&H56)+CHR$(&H67)+CHR$(&H78)+_ CHR$(&H89)+CHR$(&H9a)+CHR$(&Hab)+CHR$(&Hbc)+CHR$(&Hcd)+CHR$(&Hde)+CHR$(&Hef)+CHR$(&Hf0)+CHR$(&H10)+CHR$(&H32)+CHR$(&H54)+CHR$(&H76)+CHR$(&H98)+CHR$(&Hba)+CHR$(&Hdc)+CHR$(&Hfe) ciphertext(5)= CHR$(&Hc8)+CHR$(&H24)+CHR$(&H18)+CHR$(&H16)+CHR$(&Hf0)+CHR$(&Hd7)+CHR$(&He4)+CHR$(&H89)+CHR$(&H20)+CHR$(&Had)+CHR$(&H16)+CHR$(&Ha1)+CHR$(&H67)+CHR$(&H4e)+CHR$(&H5d)+CHR$(&H48) END SUB ' SUB TestRc6() LOCAL i, x AS LONG LOCAL sPlainText, sKey, S, sCipher, sDeCrypt AS STRING LOCAL lpSrc, lpKey,lpSubKey, lpCrypt, lpDecrypt, lpsTestCipher AS BYTE PTR DIM TestVectorsSourceMaterial(%NumberOfTestVectors) AS STATIC STRING DIM TestVectorsUserKey(%NumberOfTestVectors) AS STATIC STRING DIM TestVectorsCypher(%NumberOfTestVectors) AS STATIC STRING ' FillTestVectors(TestVectorsSourceMaterial(),TestVectorsUserKey(),TestVectorsCypher()) ' OPEN $ResultFile FOR OUTPUT AS #1 PRINT#1, "======= Result of test RC6 (all data represented in HEX format) ========================"+$CRLF+$CRLF FOR i = 0 TO %NumberOfTestVectors '------------------Source data--------------- sPlainText = TestVectorsSourceMaterial(i) lpSrc = STRPTR(sPlainText) ' sKey = TestVectorsUserKey(i) lpKey = STRPTR(sKey) '----------------------- Reserve memory for CipherText and KeySchedule------ sCipher = REPEAT$(16, CHR$(0) ) 'Allocate and reset to zero memory block for CypherText lpCrypt = STRPTR(sCipher) ' S = REPEAT$(256,CHR$(0)) ' Allocate and reset to zero memory block for KeySchedule DIM sdw(0 TO ((256/4 )-1) ) AS LOCAL DWORD AT STRPTR(S) lpSubKey = STRPTR(S) '============= Make KeySchedule and Encrypt source material ================== MakeRC6Key(lpKey, LEN(sKey), lpSubKey ) 'Rc6Encrypt16bytesBlock(lpSubKey, lpSrc, lpCrypt) ' PB version Rc6Encrypt16bytesBlockASM(lpSubKey, lpSrc, lpCrypt) ' ASM version, should be quickly. '============================= Decrypt ================================= sDeCrypt = REPEAT$(16, CHR$(0)) 'Allocate and reset to zero memory block for Decrypted material lpDecrypt = STRPTR(sDeCrypt) Rc6Decrypt16bytesBlock(lpSubKey, lpCrypt, lpDecrypt) '***************** Save results **************************************** PRINT#1, "******************************** Test vector #"+STR$(i+1)+" ********************************" PRINT#1, "-------SourceMaterial (HEX) :---" FOR x = 0 TO (LEN(sPlainText)-1) PRINT#1, HEX$(@lpSrc[x],2);" "; NEXT PRINT#1, $CRLF+"------SourceKey(Pass)(HEX) :----" FOR x = 0 TO (LEN(sKey)-1) PRINT#1, HEX$(@lpKey[x],2);" "; NEXT PRINT#1, $CRLF+"------Cipher:-------------------" FOR x = 0 TO 15 PRINT#1, HEX$(@lpCrypt[x],2); " "; NEXT PRINT#1, $CRLF+"------Cipher test vector:-------" FOR x = 0 TO 15 lpsTestCipher = STRPTR(TestVectorsCypher(i)) PRINT#1, HEX$(@lpsTestCipher[x],2); " "; NEXT PRINT#1, $CRLF+"----- Decrypted:----------------" FOR x = 0 TO (LEN(sDeCrypt)-1) PRINT#1, HEX$(@lpDecrypt[x],2); " "; NEXT #IF %DEF(%SaveKeySchedule) PRINT#1, $CRLF+"----- S ------" PRINT#1, "RC6KeySchedule:" FOR x = LBOUND(Sdw) TO UBOUND (Sdw) PRINT#1, "["+FORMAT$(x,"000")+ "] = 0x";HEX$(Sdw(x),8) NEXT #ENDIF PRINT#1, $CRLF+$CRLF NEXT ' CLOSE #1 ?"done" END SUB '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FUNCTION PBMAIN () AS LONG TestRc6() END FUNCTION