;TMG Keygenme #2 - 160Bit RSA * 2001 Goatass ;--------------------------------------------- .386 .model flat,stdcall option casemap:none WinMain proto :DWORD,:DWORD,:DWORD,:DWORD include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc include \masm32\include\gdi32.inc include \masm32\include\masm32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\gdi32.lib includelib \masm32\lib\masm32.lib GHND = GMEM_MOVEABLE OR GMEM_ZEROINIT MINCHARS = 5 MAXCHARS = 028h .data hWnd2 dd 0 ClassName db "movingCls",0 DlgName db "MyKeygen",0 AppName db "TMG Keygenme #2 160bit RSA | Goatass",0 szIcon db "KeyIcon",0 nameerr db "Username must be between 5 and 40 characters long",0 companyerr db "Company must be between 5 and 40 characters long",0 rsaerr db "RSA function returned an error",0 align 4 ;first 2 bytes are 160bit/16 (BIGNUM FORMAT) RSA_n db 00Ah,00h,0D2h,0E9h,0BFh,09Bh,03Dh,025h,08Eh,047h,09Dh,08Ch,0C2h,03Ch,07Ah,033h,0E1h,0F8h,0EBh,0B3h,0ADh,0B1h,0,0 align 4 ;first 2 bytes are 160bit/16 (BIGNUM FORMAT) RSA_d db 00Ah,00h,0C6h,054h,06Eh,00Ch,011h,0ACh,0CEh,025h,043h,0DDh,011h,050h,0C4h,0CEh,07Ah,005h,0A4h,0C8h,0FAh,03Dh,0,0 align 4 nlen dd 0 clen dd 0 .data? hInstance HINSTANCE ? CommandLine LPSTR ? szName db 60 dup(?) szCompany db 60 dup(?) szKey db 60 dup(?) szTemp db 60 dup(?) szBuffer db 60 dup(?) .const IDC_KEY equ 103 IDC_NAME equ 101 IDC_COMPANY equ 102 IDGEN equ 1 .code start: invoke GetModuleHandle, NULL mov hInstance,eax invoke GetCommandLine mov CommandLine,eax invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT invoke ExitProcess,eax WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD LOCAL wc:WNDCLASSEX LOCAL msg:MSG LOCAL hDlg:HWND mov wc.cbSize,SIZEOF WNDCLASSEX mov wc.style, CS_HREDRAW or CS_VREDRAW mov wc.lpfnWndProc, OFFSET WndProc mov wc.cbClsExtra,NULL mov wc.cbWndExtra,DLGWINDOWEXTRA push hInst pop wc.hInstance mov wc.hbrBackground,COLOR_BTNFACE+1 mov wc.lpszMenuName,NULL mov wc.lpszClassName,OFFSET ClassName invoke LoadIcon,NULL, OFFSET szIcon ;IDI_APPLICATION mov wc.hIcon,eax mov wc.hIconSm,eax invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor,eax invoke RegisterClassEx, addr wc invoke CreateDialogParam,hInstance,ADDR DlgName,NULL,NULL,NULL mov hDlg,eax invoke ShowWindow, hDlg,SW_SHOWNORMAL invoke UpdateWindow, hDlg invoke GetDlgItem,hDlg,IDC_NAME invoke SetFocus,eax .WHILE TRUE invoke GetMessage, ADDR msg,NULL,0,0 .BREAK .IF (!eax) invoke IsDialogMessage, hDlg, ADDR msg .IF eax ==FALSE invoke TranslateMessage, ADDR msg invoke DispatchMessage, ADDR msg .ENDIF .ENDW mov eax,msg.wParam ret WinMain endp WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM mov eax, hWnd mov hWnd2, eax .IF uMsg==WM_DESTROY invoke PostQuitMessage,NULL .ELSEIF uMsg==WM_COMMAND mov eax,wParam mov edx,wParam shr edx,16 .IF dx==BN_CLICKED .IF ax==IDGEN call Generate ;generates key .ENDIF .ENDIF .ELSE invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .ENDIF xor eax,eax ret WndProc endp ;------------------------------------------------------------------------------ ;###################### MANIPULATE NAME AND COMPANY ########################### ;------------------------------------------------------------------------------ ;Code ripped out of the Keygenme Mangle PROC mov edi, offset szBuffer mov word ptr [edi],0Ah add edi, 2 xor eax, eax push 5 pop ecx rep stosd dec eax mov esi, offset szName mov edi, offset szBuffer mov word ptr [edi],0Ah add edi, 2 mov ecx, nlen xor edx, edx loc_4012AA: ; CODE XREF: sub_401187+159j lodsb xor ah, al imul eax, 89177313h and eax, 55AA55AAh imul eax, 12299381h xor eax, 0AA55AA11h imul eax, 61h xor ah, al or eax, 10030118h imul eax, 988279h rcl eax, cl xor [edi+edx], eax add edx, 3 and edx, 0Fh inc edx dec ecx jg short loc_4012AA mov esi, offset szCompany mov edi, offset szBuffer mov word ptr [edi],0Ah add edi, 2 mov ecx, clen xor edx, edx loc_4012F1: ; CODE XREF: sub_401187+1A0j lodsb sub ah, al imul eax, 89157313h and eax, 55AA55AAh imul eax, 12299387h or eax, 0AA55AA11h imul eax, 61h xor eax, 10010114h imul eax, 7918279h xor ah, al rcr eax, cl xor [edi+edx], eax add edx, 3 and edx, 0Fh inc edx dec ecx jg short loc_4012F1 sub eax, [edi+8] imul eax, 34814815h add [edi+10h], eax shr eax, 0Bh and eax, 3 mov [edi], al ret Mangle ENDP ;------------------------------------------------------------------------------ ;############################ GENERATE KEY #################################### ;------------------------------------------------------------------------------ Generate PROC invoke GetDlgItemText, hWnd2, IDC_NAME, ADDR szName, MAXCHARS+1 cmp eax, MINCHARS jl @@nameerr mov nlen, eax invoke GetDlgItemText, hWnd2, IDC_COMPANY, ADDR szCompany, MAXCHARS+1 cmp eax, MINCHARS jl @@companyerr mov clen, eax call Mangle ;mangles name and company to create our M ; Keygenme uses the scheme: Serial = (Mangle(Name+Company)) ^ d mod n push 028h ;length of message to enc/dec push offset szTemp ;return buffer push offset szBuffer ;string to encrypt/decrypt push offset RSA_n ;n push offset RSA_d ;decryption exponent call RSA_PRIVATE_ENCRYPT ; Convert result to ASCII cmp eax, -1 jz @@rsaerr lea edi, szKey lea esi, szTemp movzx ecx, word ptr[esi] add ecx, ecx inc esi inc esi @@l1: xor eax, eax lodsb mov bl, al and ebx, 15 shr eax, 4 mov al, cctab[eax] mov ah, cctab[ebx] stosw dec ecx jg @@l1 and byte ptr[edi], 0 ;------------------------------------------------------------------------------ invoke SetDlgItemText, hWnd2, IDC_KEY, ADDR szKey fzk: xor eax, eax RET @@nameerr: invoke SetDlgItemText, hWnd2, IDC_NAME, ADDR nameerr jmp fzk @@companyerr: invoke SetDlgItemText, hWnd2, IDC_COMPANY, ADDR companyerr jmp fzk @@rsaerr: invoke SetDlgItemText, hWnd2, IDC_KEY, ADDR rsaerr jmp fzk cctab db "0123456789ABCDEF" Generate ENDP ;--------------------------------------------------------------------------- ;####################### RSA CODE ########################################## ;################## THANKS tHE EGOiSTE ##################################### ;*--------------------------------------------------------------------------* ; Function: int RSA_PRIVATE_ENCRYPT (P1,P2,P3,P4,P5); ; ; Description: Calculates C=M ^ D MOD N ; ; Parameters: P1) pointer to private exponent D ; P2) pointer to modulus N ; P3) pointer to message M (source buffer/plaintext) ; P4) pointer to ciphertext (destination buffer) ; P5) length of M [Bytes] ; Returns: 0 = OK ; -1 = ERROR ; Notes: D and N have to be in Bignum format used by the ; math routines. I.e. that the first WORD represents ; the SIZE of the following number in BITS divided by 16 ! ; M will be converted to Bignum format automatically. ; Ciphertext is in Bignum format with corrected byte order. ; Base for Big numbers is 16 ;*--------------------------------------------------------------------------* RSA_PRIVATE_ENCRYPT proc lpD:DWORD, lpN:DWORD, lpM:DWORD, lpC:DWORD, ml:DWORD LOCAL mem_D:DWORD, mem_N:DWORD, mem_M:DWORD, mem_Temp:DWORD,\ mem_Temp2:DWORD, mem_Result:DWORD, Bitpos:DWORD, cnt:DWORD,\ expbits:DWORD, isodd:DWORD ;USES ebx,esi,edi and isodd, 0 mov esi, lpD cmp word ptr[esi], 0 jle @@err mov eax, ml shr eax, 1 jnc @@ncs inc eax inc isodd @@ncs: mov esi, lpN cmp word ptr[esi], 0 jle @@err test ax, ax jz @@err ; cmp [esi], ax ; jl @@err ; checks if M > N very weak if it is invoke VirtualAlloc, 0, 4160, MEM_COMMIT, PAGE_READWRITE test eax, eax jz @@err mov mem_D, eax add eax, 520 mov mem_N, eax add eax, 520 mov mem_M, eax mov edi, eax add eax, 520 mov mem_Temp, eax add eax, 1040 mov mem_Temp2, eax add eax, 520 mov mem_Result, eax and word ptr[eax], 0 ; virtualalloc set this 0 already, but i'm running in paranoia mode :P ; mov ebx, ml ;convert M to BIGNUM format ; shr ebx, 1 ;not needed in our case it's already in that format ; adc ebx, 0 ; mov [edi], bx ; inc edi ; inc edi ; mov ecx, ebx ; mov esi, lpM ; cld ; rep movsw mov edi, mem_M mov esi, lpM movzx ecx, word ptr[esi] inc ecx rep movsw mov edi, mem_N mov esi, lpN movzx ecx, word ptr[esi] inc ecx rep movsw mov edi, mem_D mov esi, lpD movzx ecx, word ptr[esi] mov eax, ecx shl eax, 4 mov expbits, eax inc ecx rep movsw push 0 push mem_N call REV_BIGNUM;, mem_N, 0 ; byte order reversing needed in order to get math. correct results push isodd push mem_M call REV_BIGNUM;, mem_M, isodd ; '' push 0 push mem_D call REV_BIGNUM;, mem_D, 0 ; '' mov esi, mem_M mov edi, mem_Temp movzx ecx, word ptr[esi] inc ecx rep movsw xor edi, edi mov Bitpos, edi ; initialize bitcounter jmp @@l2 @@l1: ; ; mem_Temp = mem_Temp ^ 2 ; push mem_Temp push mem_Temp call BiG_SQR;, mem_Temp, mem_Temp ; ; mem_Temp = mem_Temp MOD mem_N */* mem_Temp2 used as Dummy to hold quotient (which is of no use here) ; push mem_Temp push mem_Temp2 push mem_N push mem_Temp call BiG_DIV;, mem_Temp, mem_N, mem_Temp2, mem_Temp dec cnt jg @@l1 mov esi, mem_Temp mov edi, mem_Result cmp word ptr[edi], 0 jnz @@nff movzx ecx, word ptr[esi] inc ecx cld rep movsw jmp @@tal @@nff: push mem_Result push mem_Temp push mem_Result call BiG_MUL;, mem_Result, mem_Temp, mem_Result push mem_Result push mem_Temp2 push mem_N push mem_Result call BiG_DIV;, mem_Result, mem_N, mem_Temp2, mem_Result @@tal: mov edi, Bitpos @@l2: inc Bitpos mov eax, expbits cmp Bitpos, eax jge @@exit mov eax, Bitpos xor edx, edx push 8 pop ebx div ebx mov esi, mem_D mov bl, [esi+eax+2] push 1 pop eax mov ecx, edx shl eax, cl test bl, al ; bit set ? jz @@l2 ; no -> test next mov eax, Bitpos sub eax, edi ; calc. delta mov cnt, eax ; init square counter jmp @@l1 @@exit: ; ; Test if final mul. is needed - thus when D is odd ; mov esi, mem_D test byte ptr[esi+2], 1 jz @@done push mem_Result push mem_M push mem_Result call BiG_MUL;, mem_Result, mem_M, mem_Result push mem_Result push mem_Temp2 push mem_N push mem_Result call BiG_DIV;, mem_Result, mem_N, mem_Temp2, mem_Result @@done: push 0 push mem_Result call REV_BIGNUM;, mem_Result, 0 mov esi, mem_Result mov edi, lpC movzx ecx, word ptr[esi] inc ecx rep movsw invoke VirtualFree, mem_D, 4160, MEM_DECOMMIT RET @@err: mov esi, lpC and word ptr[esi], 0 or eax, -1 RET RSA_PRIVATE_ENCRYPT endp ;*---------------------------------------------------* ; Function: void REV_BIGNUM(P1,P2); ; ; Description: Reverses byteorder of a Bignum ; ; Parameters: P1) pointer to Bignumber ; P2) Message Odd/Even signal ; Notes: P2 added for this keygen only! ; Returns: Always 0 ; Stack Restored on Exit ;*---------------------------------------------------* REV_BIGNUM proc push ebp mov ebp, esp sub esp, 520 mov edi, esp push ebx push edi push esi mov esi, [ebp+8] movzx ecx, word ptr[esi] cmp ecx, 256 jg @@out inc esi inc esi push esi lea edx, [ecx*2] cld rep movsw lea esi, [edi-1] pop edi mov ecx, edx sub esi, [ebp+12] sub ecx, [ebp+12] std @@l1: lodsb mov [edi], al inc edi dec ecx jg @@l1 cld @@out: pop esi pop edi pop ebx mov esp, ebp pop ebp xor eax, eax RET 8 REV_BIGNUM endp ;*-------------------------------------------------------* ; Function: int BiG_DIV(P1,P2,P3,P4); ; Description: ; Parameters: P1) pointer to Bignum to divide ; P2) pointer to Divisor ; P3) pointer to Quotient (dest. Buffer 1) ; P4) pointer to Remainder (dest. Buffer 2) ; Returns: 0 = OK ; -1 = Error (e.g. Div. by Zero) ; Stack Restored on Exit ;*-------------------------------------------------------* BiG_DIV proc push ebp mov ebp, esp sub esp, 2600 ; free some space on stack..badly needed for local copies :) mov eax, esp push ebx push edi push esi mov ebx, eax ; save start address mov esi, [ebp+8] mov edi, [ebp+12] mov ax, [esi] mov dx, [edi] test dx, dx jz @@dbzerr ; division by zero error push edi mov edi, ebx xor ecx, ecx mov cx, ax shr cx, 1 adc cx, 0 cld rep movsd movsw mov cx, ax add cx, cx lea edi, [ebx+ecx+2] and word ptr [edi], 0 pop esi lea edi, [ebx+1030] xor ecx, ecx mov cx, dx shr cx, 1 adc cx, 0 cld rep movsd movsw mov cx, dx add cx, cx lea edi, [ebx+ecx+1032] and word ptr [edi], 0 push ebp mov ebp, ebx xor eax, eax xor ecx, ecx mov ax, [ebp] test ax, ax jz @@goon add eax, eax ; ; Remove leading zeros ; mov esi, eax @@l1: cmp word ptr [ebp+esi], 0 jnz @@inzo1 sub esi, 2 jnz @@l1 @@inzo1: shr esi, 1 mov eax, esi mov word ptr [ebp], ax @@goon: mov ax, [ebp+1030] test ax, ax jz @@isdo add eax, eax mov esi, eax @@l2: cmp word ptr [ebp+esi+1030], 0 jnz @@inzo2 sub esi, 2 jnz @@l2 @@inzo2: shr esi, 1 mov eax, esi mov [ebp+1030], ax @@isdo: test ax, ax jnz @@w4 pop ebp jmp @@dbzerr @@w4: cmp word ptr [ebp], 0 jnz @@w5 pop ebp jmp @@zerdiv @@w5: xor ecx, ecx mov cx, [ebp] cmp cx, [ebp+1030] jc @@dab jnz @@dchs mov eax, ecx add eax, eax lea esi, [ebp] lea edi, [ebp+1030] add esi, eax add edi, eax std repz cmpsw cld jc @@dab @@dchs: mov ax, [ebp+1030] shr ax, 1 adc ax, 0 cmp ax, 1 jz @@shdiv ; ; Start division ; xor eax, eax mov ax, [ebp+1030] shr ax, 1 adc ax, 0 mov esi, eax shl esi, 2 sub esi, 2 cmp esi, 10 jb @@dm1a mov ebx, [ebp+esi+1030] mov eax, [ebp+esi+1026] mov edx, [ebp+esi+1022] xor ecx, ecx @@l3: cmp ebx, 80000000h ; check for 2^31 overflow jae @@dm2 inc cx clc rcl edx, 1 rcl eax, 1 rcl ebx, 1 jmp @@l3 @@dm1a: mov ebx, [ebp+esi+1030] mov eax, [ebp+esi+1026] xor ecx, ecx ; init cnt @@l4: cmp ebx, 80000000h jae @@dm2 inc cx clc rcl eax, 1 rcl ebx, 1 jmp @@l4 @@dm2: mov [ebp+2578], cx ; save exp. mov [ebp+2570], ebx mov [ebp+2574], eax @@dm3: inc word ptr [ebp] inc word ptr [ebp] xor eax, eax mov ax, [ebp] shr ax, 1 adc ax, 0 mov esi, eax shl esi, 2 sub esi, 2 mov dword ptr [ebp+esi], 0 xor eax, eax mov ax, [ebp+1030] shr ax, 1 adc ax, 0 mov esi, eax shl esi, 2 sub esi, 2 xor ecx, ecx mov cx, [ebp] shr cx, 1 adc cx, 0 mov edi, ecx shl edi, 2 sub edi, 2 push edi sub edi, esi inc edi mov ecx, edi shr ecx, 2 pop esi sub edi, 3 push edi ; ; Division loop ; @@sdm: cmp esi, 14 jb @@dib push edi mov edx, [ebp+esi] mov eax, [ebp+esi-4] mov ebx, [ebp+esi-8] mov edi, [ebp+esi-12] push ecx mov cx, [ebp+2578] @@l5: test cx, cx jz @@w6 rcl edi, 1 rcl ebx, 1 rcl eax, 1 rcl edx, 1 dec cx jmp @@l5 @@w6: pop ecx pop edi jmp @@cqd @@dib: mov edx, [ebp+esi] mov eax, [ebp+esi-4] mov ebx, [ebp+esi-8] push ecx mov cx, [ebp+2578] @@l6: cmp cx, 0 jz @@w7 rcl ebx, 1 rcl eax, 1 rcl edx, 1 dec cx jmp @@l6 @@w7: pop ecx @@cqd: mov [ebp+2582], eax mov [ebp+2586], ebx mov ebx, [ebp+2570] cmp ebx, edx jz @@bm1 div ebx ; eax => mv mov [ebp+2566], eax test eax, eax jnz @@w8 jmp @@dml @@bm1: xor eax, eax dec eax mov [ebp+2566], eax mov edx, [ebp+2582] add edx, [ebp+2570] jc @@sdo @@w8: mov ebx, edx mul dword ptr [ebp+2574] cmp edx, ebx jb @@sdo ja @@w9 cmp eax, [ebp+2586] jbe @@sdo @@w9: dec dword ptr [ebp+2566] ; correct mv add ebx, [ebp+2570] jc @@sdo sub eax, [ebp+2574] sbb edx, 0 cmp edx, ebx jb @@sdo ja @@w9 cmp eax, [ebp+2586] ja @@w9 @@sdo: push ecx push esi push edi mov cx, [ebp+1030] shr cx, 1 adc cx, 0 mov ebx, [ebp+2566] ; MulSub() push 2 pop esi xor edx, edx ; rem. dummy @@msl: push edx mov eax, ebx mul dword ptr [ebp+esi+1030] sub [ebp+edi], eax adc edx, 0 pop eax sub [ebp+edi], eax adc edx, 0 add edi, 4 add esi, 4 loop @@msl sub [ebp+edi], edx jnc @@dnc ; Correct on cs pop edi push edi xor ecx, ecx mov cx, [ebp+1030] shr cx, 1 adc cx, 0 push 2 pop esi clc @@sdw: mov eax, [ebp+esi+1030] adc [ebp+edi], eax add edi, 4 add esi, 4 loop @@sdw jnc @@sdx inc dword ptr [ebp+edi] @@sdx: dec dword ptr [ebp+2566] @@dnc: pop edi pop esi pop ecx @@dml: mov eax, [ebp+2566] mov [ebp+edi+1546], eax sub edi, 4 sub esi, 4 dec ecx jz @@sdz jmp @@sdm @@sdz: pop edi add edi, 2 xor eax, eax @@l7: cmp ax, [ebp+edi+1546] jnz @@sdr sub edi, 2 jnz @@l7 @@sdr: mov edx, edi shr edx, 1 mov [ebp+1546], dx ; Check for rem. len xor eax, eax mov ax, [ebp+1030] mov ecx, eax add ax, ax mov edi, eax xor ebx, ebx add edi, 2 @@sdu: sub edi, 2 cmp [ebp+edi], bx loopz @@sdu jz @@sdv inc cx @@sdv: mov [ebp], cx ; Save results @@savd: mov esi, ebp mov ebx, ebp pop ebp push esi add esi, 1546 mov edi, [ebp+16] xor ecx, ecx mov cx, [esi] shr cx, 1 adc cx, 0 cld test cx, cx jz @@quot0 rep movsd @@quot0: movsw pop esi @@drs: mov edi, [ebp+20] xor ecx, ecx mov cx, [esi] shr cx, 1 adc cx, 0 cld test ecx, ecx jz @@rem0 rep movsd @@rem0: movsw xor eax, eax @@rfdiv: pop esi pop edi pop ebx mov esp, ebp pop ebp RET 16 ; restore stack / get rid of parameters @@zerdiv: xor eax, eax mov edi, [ebp+20] mov esi, [ebp+16] mov [edi], ax mov [esi], ax jmp @@rfdiv @@dbzerr: or eax, -1 ; return error jmp @@rfdiv @@dab: mov esi, ebp mov ebx, ebp pop ebp mov edi, [ebp+16] mov word ptr [edi], 0 jmp @@drs @@shdiv: xor ecx, ecx mov cx, [ebp] shr cx, 1 adc cx, 0 mov edi, ecx shl edi, 2 sub edi, 2 xor edx, edx mov ebx, [ebp+1032] @@dsh1: mov eax, [ebp+edi] div ebx mov [ebp+edi+1546], eax sub edi, 4 loop @@dsh1 @@dsh2: xor ecx, ecx mov cx, [ebp] mov esi, ecx add esi, esi @@l8: mov bx, [ebp+esi+1546] test bx, bx jnz @@dsh3 dec esi dec esi dec ecx test cx, cx jnz @@l8 @@dsh3: mov [ebp+1546], cx mov [ebp+2], edx mov word ptr [ebp], 2 cmp word ptr [ebp+4], 0 jnz @@dst mov word ptr [ebp], 1 cmp word ptr [ebp+2], 0 jnz @@dst and word ptr [ebp], 0 @@dst: jmp @@savd BiG_DIV endp ;*-------------------------------------------------------* ; Function: void BiG_SQR(P1,P2); ; ; Description: Calculates Square of a given X => X*X ; (Faster than BiG_MUL !) ; Parameters: P1) pointer to Bignum to square ; P2) pointer to (result)buffer ; Returns: Always 0 ; Stack Restored on Exit ;*-------------------------------------------------------* BiG_SQR proc push ebp mov ebp, esp sub esp, 1560 mov eax, esp push ebx push edi push esi mov ebx, eax mov esi, [ebp+8] mov dx, [esi] test dx, dx jz @@pow0 lea edi, [ebx] xor ecx, ecx mov cx, dx cld rep movsw movsw and word ptr [edi], 0 push ebp mov ebp, ebx ; Kill leading 0s xor eax, eax mov ax, [ebp] test ax, ax jz @@goon add eax, eax mov esi, eax ; obase @@l1: cmp word ptr [ebp+esi], 0 jnz @@inzo1 sub esi, 2 jnz @@l1 @@inzo1: shr esi, 1 mov eax, esi mov [ebp], ax @@goon: test ax, ax jnz @@mpow2 pop ebp jmp @@pow0 @@mpow2: xor ecx, ecx mov cx, [ebp] shr cx, 1 adc cx, 0 cmp cx, 1 jz @@regpow xor eax, eax push 2 pop esi @@lsqrW: mov [ebp+esi+520], eax add esi, 4 loop @@lsqrW push 2 pop esi xor ecx, ecx mov cx, [ebp] shr cx, 1 jc @@lsqrV dec cx @@lsqrV: push ecx mov edi, esi add edi, 4 xor ecx, ecx mov cx, [ebp] shr cx, 1 adc cx, 0 push esi add esi, 2 shr esi, 2 sub ecx, esi pop esi xor edx, edx mov ebx, [ebp+esi] add esi, edi @@lsqrU: push ecx mov ecx, edx mov eax, ebx mul dword ptr [ebp+edi] add eax, ecx adc edx, 0 add [ebp+esi+518], eax adc edx, 0 add edi, 4 add esi, 4 pop ecx loop @@lsqrU mov [ebp+esi+518], edx sub esi, edi add esi, 4 pop ecx loop @@lsqrV add esi, edi and dword ptr [ebp+esi+518], 0 and dword ptr [ebp+esi+522], 0 ; tempres = tempres * 2 push 6 ; skip 0 part pop esi xor ecx, ecx mov cx, [ebp] @@tr2l: rcl dword ptr[ebp+esi+520], 1 inc esi ; inc doesn't affest c flag. so better don't change it to add ,4 ;) inc esi inc esi inc esi loop @@tr2l ; Add squares mov cx, [ebp] add cx, cx mov [ebp+520], cx push 2 pop esi mov edi, esi mov cx, [ebp] shr cx, 1 adc cx, 0 xor eax, eax pushf ; dummy @@lsqr2: mov eax, [ebp+esi] mul eax popf adc [ebp+edi+520], eax adc [ebp+edi+524], edx pushf add esi, 4 add edi, 8 loop @@lsqr2 popf ; stack corr. only jmp @@lsqrX @@regpow: mov eax, [ebp+2] mul eax mov [ebp+522], eax mov [ebp+526], edx mov word ptr [ebp+520], 4 @@lsqrX: xor eax, eax mov ax, [ebp+520] mov edi, eax add edi, edi cmp word ptr [ebp+edi+520], 0 jnz @@lsqrY dec word ptr [ebp+520] jmp @@lsqrX @@lsqrY: lea esi, [ebp+520] mov ebx, ebp pop ebp mov edi, [ebp+12] xor ecx, ecx mov cx, [esi] shr cx, 1 adc cx, 0 jz @@w5 cld rep movsd @@w5: movsw @@rfsq: ; return from square :P pop esi pop edi pop ebx mov esp, ebp pop ebp xor eax, eax RET 8 ; restore stack / get rid of parameters @@pow0: mov esi, [ebp+12] and word ptr [esi], 0 ; set bignum 0 jmp @@rfsq BiG_SQR endp ;*-------------------------------------------------------* ; Function: void BiG_MUL(P1,P2,P3); ; Description: ; Parameters: P1) pointer to Bignum factor 1 ; P2) pointer to Bignum factor 2 ; P2) pointer to (result)buffer ; Returns: Always 0 ; Stack Restored on Exit ;*-------------------------------------------------------* BiG_MUL proc push ebp mov ebp, esp sub esp, 2200 cld mov eax, esp push edi push esi push ebx mov ebx, eax xor eax, eax xor edx, edx mov esi, [ebp+8] mov edi, [ebp+12] mov ax, [esi] mov dx, [edi] test ax, ax jz @@mul0 test dx, dx jz @@mul0 push edi lea edi, [ebx+520] xor ecx, ecx mov cx, ax rep movsw movsw and word ptr [edi], 0 pop esi lea edi, [ebx] mov cx, dx rep movsw movsw and word ptr [edi], 0 push ebp mov ebp, ebx xor eax, eax mov ax, [ebp+520] test ax, ax jz @@goon add eax, eax mov esi, eax @@l1: cmp word ptr [ebp+esi+520], 0 jnz @@inzo1 sub esi, 2 jnz @@l1 @@inzo1: shr esi, 1 mov eax, esi mov 520[ebp], ax @@goon: mov ax, [ebp] test ax, ax jz @@iszer add eax, eax mov esi, eax @@l2: cmp word ptr [ebp+esi], 0 jnz @@inzo2 sub esi, 2 jnz @@l2 @@inzo2: shr esi, 1 mov eax, esi mov [ebp], ax @@iszer: test ax, ax jnz @@w1 pop ebp jmp @@mul0 @@w1: cmp word ptr [ebp+520], 0 jnz @@w2 pop ebp jmp @@mul0 ; start @@w2: push 2 pop esi mov cx, dx shr cx, 1 adc cx, 0 xor eax, eax @@mxx: mov [ebp+esi+1040], eax add esi, 4 loop @@mxx mov esi, 2 xor ecx, ecx mov cx, [ebp+520] shr cx, 1 adc cx, 0 ; outter loop @@mxw: push ecx mov edi, 2 mov cx, [ebp] shr cx, 1 adc cx, 0 xor edx, edx ; dummy mov ebx, [ebp+esi+520] add esi, edi ; inner loop @@mxy: push ecx mov ecx, edx mov eax, ebx mul dword ptr [ebp+edi] add eax, ecx adc edx, 0 add [ebp+esi+1038], eax adc edx, 0 add edi, 4 add esi, 4 pop ecx loop @@mxy mov [ebp+esi+1038], edx sub esi, edi add esi, 4 pop ecx loop @@mxw add esi, edi sub esi, 4 @@mxz: cmp word ptr [ebp+esi+1040], 0 jnz @@mxv sub esi, 2 jmp @@mxz @@mxv: mov ecx, esi shr ecx, 1 mov [ebp+1040], cx ;Save result lea esi, [ebp+1040] mov ebx, ebp pop ebp mov edi, [ebp+16] test cx, cx jz @@w3 cld rep movsw @@w3: movsw @@rfmul: pop ebx pop esi pop edi mov esp, ebp pop ebp xor eax, eax RET 12 ; restore stack / get rid of parameters @@mul0: mov esi, [ebp+16] and word ptr [esi], 0 ; clear bignum jmp @@rfmul BiG_MUL endp ;--------------------------------------------------------------------------------------- end start