⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rsa.asm

📁 用于RSA加密的汇编语言源代码
💻 ASM
字号:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		.386
		.model flat, stdcall
		option casemap :none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include		windows.inc
include		user32.inc
includelib	user32.lib
include		kernel32.inc
includelib	kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN	equ		1000	;图标
DLG_MAIN	equ		100

DD_NUM	        EQU              8;32		;位数除以32,即DWORD数
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		.data?

hInstance	dd	?

actural_b	dd	DD_NUM * 2 dup (0)
actural_n	dd	DD_NUM * 2 dup (0)
actural_m	dd	DD_NUM * 2 dup (0)
result		dd	DD_NUM * 2 dup (0)
presult		dd	?

		.data

rsa_a	dd	DD_NUM dup (0)
rsa_b	dd	DD_NUM dup (0)
rsa_c	dd	DD_NUM dup (0)
rsa_n	dd	DD_NUM dup (0)
rsa_p	dd	DD_NUM dup (0)
rsa_m	dd	DD_NUM dup (0)
rsa_back dd	DD_NUM dup (0)

		.const
default_b	db	"10001",0	        ;设置默认的私钥
default_n	db	"C7B71C573A60F571",0	;设置默认的模
default_m	db	"BCF0DB712E6595F1",0	;设置默认的数据
num_error	db	"有非法字符!",0
blank_error	db	"输入所有数据!",0
format		db	 "%X",0
format8		db	 "%8X",0
can_not_factor	db	"这个n是素数,不能分解!",0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
rsa	proc
	push ebp
	mov  ebp,esp
 
;------------------------------;  置初值
	mov rsa_c,1
;------------------------------;  循环计算
rsa0:	mov eax,rsa_b		  ;bl; 
	and eax,1				;b&1
	.if eax == 0				;b偶数?
;------------------------------b = b >> 1	;b是偶数时
		rcl eax,1		
		mov esi,DD_NUM                  ;2
		.repeat
			rcr eax,1
			rcr [rsa_b-4+esi*4],1	
			rcl eax,1
			dec esi
		.until esi == 0
;------------------------------a = (a * a) mod n
		lea  eax,rsa_a	;c--[EBP-08h][EBP-04h] 
		call bigmul		;<--调用两数相乘再除以n的子程序
		lea  eax,rsa_a	;c--[EBP-08h][EBP-04h] 
		call bigdiv
	.else
		sub rsa_b,1	;b = b - 1 只需将b的最低位置0即可
;------------------------------c = (c * a) mod n
		lea  eax,rsa_c		;a
		call bigmul		;<--调用两数相乘再除以n的子程序
		lea  eax,rsa_c		;a
		call bigdiv
	.endif
;------------------------------判断b是否0  while(b)
	mov esi,DD_NUM ;
	.repeat
		cmp [rsa_b-4+esi*4],0	;判断b是否0
		ja rsa0
		dec esi
	.until esi == 0
;------------------------------计算结束
	pop      ebp
	retn
rsa	endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;-----------------------------两数相乘的子程序,这里利用了数据连续存储的特点,乘积的长度与两个数据一样,
bigmul	proc			;超出的部分会自动存到余数所在的空间
	mov ebx,eax		;唯一的一个输入参数,是一个乘数的地址,另一个乘数固定为rsa_a
	lea ecx,rsa_a		;乘积存放在rsa_p和rsa_m合起来的连续空间
	xor eax,eax
	xor esi,esi
	.repeat
		mov [rsa_p+esi*4],eax		;乘积置初值0
		inc esi
	.until  esi == DD_NUM + DD_NUM ;4

	xor edi,edi
	push ebp
	.repeat
		lea ecx,[ecx+edi*4]		;ecx=ecx+edi*4
		xor esi,esi			;esi=0
		lea ebp,[rsa_p+edi*4]
		.repeat
			mov eax,[ebx+esi*4]
			mul DWORD ptr [ecx]
			lea ebp,[ebp+esi*4]
			add DWORD ptr [ebp],eax
			adc DWORD ptr [ebp+4],edx
			adc DWORD ptr [ebp+8],0
			inc esi
		.until esi == DD_NUM ;
		inc edi
	.until edi == DD_NUM ;
	pop ebp
	retn
bigmul	endp
;--------------------------------两个数相除 取余数
bigdiv	proc			;被除数为rsa_p,存在于rsa_p至rsa_m的连续空间,除数为rsa_n
	mov ebx,eax
	mov edx,DD_NUM * 20H ;<--设循环次数

mydiv:	xor esi,esi
	inc esi
	mov ecx,DD_NUM + DD_NUM - 1
	shl DWORD ptr [rsa_p],1;被除数左移1位,rsa_p至rsa_m连续左移
shiftp:	rcl DWORD ptr [rsa_p+esi*4],1
	inc esi
	loop shiftp

	mov esi,DD_NUM;2		;比较
	.repeat
		mov eax,[rsa_n-4+esi*4]
		cmp [rsa_m-4+esi*4],eax
		jc  loop0
		ja  asubb
		dec esi
	.until esi == 0

asubb:	xor esi,esi		;相减
	clc
	mov ecx,DD_NUM
msubn:	mov eax,[rsa_n+esi*4]
	sbb [rsa_m+esi*4],eax
	inc esi
	loop msubn

	inc DWORD ptr [rsa_p]	;为了取商,加上了这一段
	xor esi,esi
	inc esi
	mov ecx,DD_NUM - 1
padd1:	adc DWORD ptr [rsa_p+esi*4],0
	inc esi
	loop padd1

loop0:	dec edx
	jnz mydiv
;相除结束,[rsa_p]是商,[rsa_m]是余数
	xor esi,esi
	.repeat
		mov eax,[rsa_m+esi*4]		;保存余数
		mov [ebx+esi*4],eax
		inc esi
	.until esi == DD_NUM ;2

	retn
bigdiv	endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
scan_data	proc	hWnd
;检查输入数据的长度
	mov edi,eax
	invoke lstrlen,eax
	.if eax ==0 
		jmp nonum
	.endif

;检查输入数据中是否有非法字符
scan_b:
	mov al,BYTE ptr [edi]
	.if al == 0
		xor eax,eax
		inc eax
		jmp scan_end
	.elseif al >= '0' && al <= '9' || al >= 'A' && al <= 'F' || al >= 'a' && al <= 'f'
		inc edi
		jmp scan_b
	.else
		jmp notnum
	.endif
notnum:	
	invoke SetDlgItemText,hWnd,104,addr num_error
	xor eax,eax
	jmp scan_end
nonum:	
	invoke SetDlgItemText,hWnd,104,addr blank_error
	xor eax,eax
scan_end:
	pop ebp
	retn 4
scan_data	endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
stringtoint	proc
	mov esi,eax
	mov edi,edx
	invoke lstrlen,eax
	xchg eax,esi
	mov edx,edi
	xor ebx,ebx
conv:	mov cl,BYTE ptr [eax+esi-1]
	.if cl >= 'A' && cl <= 'F'
		sub cl,'A'-0ah
	.elseif cl >= 'a' && cl <= 'f'
		sub cl,'a'-0ah
	.else
		sub cl,'0'
	.endif
	mov bl,cl

	dec esi
	jz oddbit
	mov cl,BYTE ptr [eax+esi-1]
	.if cl >= 'A' && cl <= 'F'
		sub cl,'A'-0ah
	.elseif cl >= 'a' && cl <= 'f'
		sub cl,'a'-0ah
	.else
		sub cl,'0'
	.endif
	shl cl,4
	add bl,cl
	mov BYTE ptr [edx],bl
	inc edx
	dec esi
	jnz conv
	jmp convert_end

oddbit:	mov BYTE ptr [edx],bl
	
convert_end:
	retn
stringtoint	endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
inttostring	proc
	mov esi,eax
	mov edi,edx
	invoke lstrlen,eax
	cdq
	mov ecx,4
	div ecx
	mov ebx,eax
	xor eax,eax
	lea eax,result
	mov presult,eax
	.if edx != 0
		mov eax,DWORD ptr [esi+ebx*4]
		invoke wsprintf,presult,addr format,eax
		add presult,eax
	.endif
	.while ebx > 0
		mov eax,DWORD ptr [esi+ebx*4-4]
		invoke wsprintf,presult,addr format,eax
		add presult,eax
		dec ebx
	.endw
	retn
inttostring	endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcDlgMain	proc	uses ebx edi esi hWnd,wMsg,wParam,lParam

		mov	eax,wMsg
		.if	eax == WM_CLOSE
			invoke	EndDialog,hWnd,NULL
		.elseif	eax == WM_INITDIALOG
			invoke	LoadIcon,hInstance,ICO_MAIN
			invoke	SendMessage,hWnd,WM_SETICON,ICON_BIG,eax
			invoke SetDlgItemText,hWnd,101,addr default_b
			invoke SetDlgItemText,hWnd,102,addr default_n
			invoke SetDlgItemText,hWnd,103,addr default_m
		.elseif	eax == WM_COMMAND
			mov	eax,wParam
			.if	ax == IDCANCEL 
				invoke	EndDialog,hWnd,NULL
			.elseif	ax == IDOK
				invoke SetDlgItemText,hWnd,104,NULL 
				lea eax,actural_b
				xor edx,edx
				mov ecx,DD_NUM * 8 + 1 
clrmem:				mov [eax + ecx * 4 - 4],edx
				loop clrmem
				lea eax,rsa_a
				mov ecx,DD_NUM * 6 + 1
clrmem1:			mov [eax + ecx * 4 - 4],edx
				loop clrmem1

				invoke GetDlgItemText,hWnd,101,addr actural_b,sizeof actural_b
				invoke GetDlgItemText,hWnd,102,addr actural_n,sizeof actural_n
				invoke GetDlgItemText,hWnd,103,addr actural_m,sizeof actural_m
				lea eax,actural_b
				invoke scan_data,hWnd
				.if eax 
					lea eax,actural_n
					invoke scan_data,hWnd
					.if eax
						lea eax,actural_m
						invoke scan_data,hWnd
						.if eax 
							lea eax,actural_b
							lea edx,rsa_b
							call stringtoint
							lea eax,actural_n
							lea edx,rsa_n
							call stringtoint
							lea eax,actural_m
							lea edx,rsa_a
							call stringtoint
							call rsa
							lea eax,rsa_c
							lea edx,result
							call inttostring
							invoke SetDlgItemText,hWnd,104,addr result
						.endif
					.endif
				.endif
			.endif
		.else
			mov	eax,FALSE
			ret
		.endif
		mov	eax,TRUE
		ret

_ProcDlgMain	endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
		invoke	GetModuleHandle,NULL
		mov	hInstance,eax
		invoke	DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,NULL
		invoke	ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		end	start

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -