• 标 题:奉献一个能进行rsa计算的小工具
  • 作 者:moon
  • 时 间:2004-07-10,19:23
  • 链 接:http://bbs.pediy.com

好久没有作品可以放上来与大家分享了,今特奉上一款本人独立创作完成的完全用汇编语言编写而成的小工具"rsa计算器"。输入输出全部都用十六进制格式,可对数据进行运算,而不是对文本。

点击下载:附件!

n能到1024位。也有疑问,位数再高不知为何不行。(改变DD_NUM等值的数即可改变位数)

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    .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