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

📄 2fish_86.asm

📁 一个towfish加密算法的源代码
💻 ASM
📖 第 1 页 / 共 4 页
字号:
	shr		ebx,16
	mov		edi,S32_2[SBS*edi]
	xor		esi,ecx

	mov		edx,S32_1[SBS*edx]
	movzx	ecx,ah
	movzx	eax,al

  if (KEY_MODE and (KM_FULL or KM_COMPILE)) eq 0
	doSbox	keySize,cpuName,ecx,eax,3,2
  endif

	mov		ecx,S32_3[SBS*ecx]
	xor		edi,edx
	movzx	edx,bh

	mov		eax,S32_2[SBS*eax]
	movzx	ebx,bl
	xor		esi,ecx

  if (KEY_MODE and (KM_FULL or KM_COMPILE)) eq 0
	doSbox	keySize,cpuName,edx,ebx,0,3
  endif

	mov		edx,S32_0[SBS*edx]
	xor		esi,eax

	mov		ebx,S32_3[SBS*ebx]
	xor		edi,edx

  if (KEY_MODE and KM_COMPILE) eq 0
	GetSubkey lbl,eax,S_INDEX
	xor		edi,ebx

	GetSubkey lbl,ebx,S_INDEX+4
	add		esi,edi				;first half of the PHT

	add		edi,esi				;complete the PHT
	add		esi,eax				;add in the round subkeys
	mov		eax,z2				;load z2,z3 to update them

	add		edi,ebx
	mov		ebx,z3
   ifdif <lbl>,<Enc>
	rol		eax,1				;Decryption: z2=ROL(z2,1)
	xor		ebx,edi				;complete the Feistel xor

	ror		ebx,1				;Decryption: z3=ROR(z3,1)
	xor		eax,esi				;half of Feistel xor
   else
	xor		eax,esi				;half of Feistel xor

	rol		ebx,1				;Encryption: z3=ROL(z3,1)

	ror		eax,1				;Encryption: z2=ROR(z2,1)
	xor		ebx,edi				;complete Feistel. eax,ebx=new z2,z3
   endif
  else ;---"Compiled" constants code here
   ifdif <lbl>,<Enc>			;---do Decryption first
	xor		edi,ebx				;compute edi=final value of t1
	mov		eax,z2				;eax=x[2]

	mov		ebx,z3
	lea		edx,[esi+2*edi+12345678h]	;no AGI!
concat Dec_SK_,%((S_INDEX+4)/4),<_>,cpuName,<:>	;label so we can "patch" code
	rol		eax,1				;Decryption: z2=ROL(z2,1)
	
	lea		ecx,[esi+edi+12345678h+4]
concat Dec_SK_,%((S_INDEX+0)/4),<_>,cpuName,<:>
	xor		ebx,edx				;complete the Feistel xor

	ror		ebx,1				;Decryption: z3=ROR(z3,1)
	xor		eax,ecx				;half of Feistel xor
   else	 ;--- handle Encryption compilation here
	xor		edi,ebx		
	mov		ebx,z3

	mov		eax,z2
	lea		ecx,[esi+edi+12345678h+4]	;no AGI!
concat Enc_SK_,%((S_INDEX+0)/4),<_>,cpuName,<:>
	rol		ebx,1				;Encryption: z3=ROL(z3,1)
	
	lea		edx,[esi+2*edi+12345678h]
concat Enc_SK_,%((S_INDEX+4)/4),<_>,cpuName,<:>
	xor		eax,ecx				;half of Feistel xor

	ror		eax,1				;Encryption: z2=ROR(z2,1)
	xor		ebx,edx				;complete Feistel. eax,ebx=new z2,z3
   endif
  endif
 endif
endm

SetSboxK8 macro cpuName
 ifidn <cpuName>,<PentiumPro>	;split SboxKey into bytes...
  if KEY_MODE and KM_MIN		;and store as dwords	
	mov		edx,ks.sboxKeys[0]
	movzx	eax,dl					
	movzx	ebx,dh
	mov		sboxK8,eax
	shr		edx,16
	movzx	eax,dh
	mov		sboxK8+4,ebx
	movzx	edx,dl
	mov		sboxK8+12,eax
	mov		sboxK8+8,edx
  endif
 endif
endm

x0			equ		<x[0]>
x1			equ		<x[4]>
x2			equ		<x[8]>
x3			equ		<x[12]>

; do two rounds (subKeys are in reverse order)
Encrypt2Rounds	macro	roundNum,cpuName		;__TRANSPARENT__
	RoundFunc	,Enc,cpuName,x0,x1,x2,x3,%(roundNum)  ,%(ROUND_SUBKEYS+8*(MAX_ROUNDS-roundNum-1))
	RoundFunc	,Enc,cpuName,x2,x3,x0,x1,%(roundNum+1),%(ROUND_SUBKEYS+8*(MAX_ROUNDS-roundNum-2))
endm

; do two rounds
Decrypt2Rounds	macro	roundNum,cpuName		;__TRANSPARENT__
	RoundFunc	,Dec,cpuName,x2,x3,x0,x1,%(roundNum+1),%(ROUND_SUBKEYS+8*roundNum+8))
	RoundFunc	,Dec,cpuName,x0,x1,x2,x3,%(roundNum)  ,%(ROUND_SUBKEYS+8*roundNum))
endm
;
;----------------------------------------------------------------------------------
;		Encryption
;----------------------------------------------------------------------------------
;
	varOffs =	0
	alloc	x,dword,BLOCK_SIZE/8	;local copy of text
  if KEY_MODE and KM_MIN
	alloc	sboxK8,dword,4*4		;for Pentium Pro MIN_KEY mode
  endif
  if KEY_MODE and KM_ZERO
	alloc	roundNum,dword,4		;"soft" round number
	alloc	roundJmpPtr,dword,4		;dispatch based on key size
  endif
	alloc	IVptr,dword,4			;ptr to CBC IV (NULL --> ECB)
	localSize = varOffs
	alloc	regs,dword,8*4			;pushad puts regs here
	alloc	retAddr,dword,4			;esp --> here on entry
	alloc	cipherPtr,dword,4		;pointer to cipher (includes mode)
	alloc	ksPtr,dword,4			;pointer to initialized key schedule
	alloc	inputPtr,dword,4		;pointer to plaintext to encrypt
	alloc	inputLen,dword,4		;# bits to encrypt
	alloc	outBuffer,dword,4		;where to put ciphertext
retVal	equ regs[28]

cipherProc	macro	cpuName			;instantiate encrypt/decrypt functions
cipherProcStart_&cpuName:
TwoFishEncrypt_&cpuName proc
	pushad							;save all regs
	sub		esp,localSize			;set up local stack frame

	mov		ebp,ksPtr
	mov		edx,cipherPtr

	mov		esi,inputPtr			;is the text "in-place"?
	mov		edi,outBuffer

	mov		ecx,inputLen
	cmp		esi,edi

	mov		retVal,ecx				;save length as return value
	iff		nz						;if not, make it so
	  shr	ecx,5					;convert from bits to dwords
	 ifdif <cpuName>,<PentiumPro>
	  mov	eax,[edi]				;load some cache lines (for Pentium)
	  mov	ebx,[edi+32]
     endif
	  rep	movsd					;put the text in place
	endi

	biasEBP							;point EBP to Sbox 
	mov		al,[edx].mode			;figure out if we are in CBC mode

	cmp		al,MODE_CBC				;if so, make local copy of IV
	iff z
	  lea	edi,[edx+IV32]			;point edi directly to IV32
	elsef
	  xor	edi,edi					;NULL IVptr --> ECB mode
	endi

	SetSboxK8	cpuName
  if KEY_MODE and KM_ZERO
	mov		eax,ks.keyLen
	shr		eax,6					;divide by 64
	mov		eax,encJmpTab_&cpuName[4*eax-4]
	mov		roundJmpPtr,eax			;save dispatch address
  endif
	mov		esi,outBuffer			;set up for loop
	mov		IVptr,edi				;save IV ptr

	or		edi,edi
	iff nz
	  ;read plaintext block to x, add input whitening and IV input
	  ;edi == IVptr here
Enc_CBC_&cpuName:
	  Xor8	Enc_CBC,cpuName,x+8,[esi+8],INPUT_WHITEN+8,[edi+8]
	  Xor8	Enc_CBC,cpuName,   ,[esi]  ,INPUT_WHITEN  ,[edi]
	elsef
	align	4
Enc_ECB_&cpuName:
	  ;read plaintext block to x, add input whitening
	  Xor8	Enc,cpuName,x+8,[esi+8],INPUT_WHITEN+8
	  Xor8	Enc,cpuName,   ,[esi]  ,INPUT_WHITEN
	endi

	;whitening/IV merged in. Now we're ready to encrypt
	;eax=x0, ebx=x1. (already loaded from INPUT_WHITEN xor)
  ifdif		<cpuName>,<PentiumPro>
	xor		ecx,ecx					;zero out high bits
   if EDX_ADJUST
	mov		edx,EDX_ADJUST
   else
    xor		edx,edx
   endif
  endif

  if KEY_MODE and KM_ZERO
	mov		roundNum,14
	jmp		roundJmpPtr				;dispatch to appropriate handler
   irp _kSize,<256,192,128>
concat <encLoop_>,%(_kSize),<_>,cpuName:
	RoundFunc	_kSize,Enc,cpuName,x0,x1,x2,x3,0,8
	RoundFunc	_kSize,Enc,cpuName,x2,x3,x0,x1,1,0
	sub		roundNum,2
concat <jae encLoop_>,%(_kSize),<_>,cpuName
	if _kSize ne 128
	  jmp	encDone_&cpuName
	endif
   endm
encDone_&cpuName:
  else
	Encrypt2Rounds	0,cpuName
	Encrypt2Rounds	2,cpuName
	Encrypt2Rounds	4,cpuName
	Encrypt2Rounds	6,cpuName

	Encrypt2Rounds	8,cpuName
	Encrypt2Rounds	10,cpuName
	Encrypt2Rounds	12,cpuName
	Encrypt2Rounds	14,cpuName
  endif

	; here with eax=x0,ebx=x1, **unstored**.
	; done with encryption.	 Add output whitening
	mov		edi,IVptr				;get ready to test CBC mode below
	mov		esi,outBuffer

	Xor8	Enc,cpuName,[esi+8],   ,OUTPUT_WHITEN+8
	Xor8	Enc,cpuName,[esi]  ,x+8,OUTPUT_WHITEN

	add		esi,BLOCK_SIZE/8
	mov		ecx,inputLen

	mov		outBuffer,esi			;save updated buffer ptr
	sub		ecx,BLOCK_SIZE			;are we done yet?

	mov		inputLen,ecx			;save updated length

	or		edi,edi					;are we in CBC mode?
	iff z
	  or	ecx,ecx
	  jg	Enc_ECB_&cpuName		;we can only do 2Gbits per call!
	elsef
	  Copy8	[edi]					;if so, save new IV for next time
	  Copy8	[edi+8],[esi-8]			;[esi-8] because we just added 16 to esi

	  or	ecx,ecx
	  jg	Enc_CBC_&cpuName
	endi

	; clean up stack and return
	add		esp,localSize
	popad							;restore regs, including retVal to eax
	ret

  if KEY_MODE and KM_ZERO
encJmpTab_&cpuName	label	dword
		dd	encLoop_128_&cpuName,encLoop_128_&cpuName	
		dd	encLoop_192_&cpuName,encLoop_256_&cpuName
  endif

 if KEY_MODE and KM_COMPILE			;make a subkey compilation "patch" list
PatchList_Enc_&cpuName	label	dword
QQ=0
  rept	8
	irp SKn,<%QQ>
concat	<  dd Enc_SK_>,%(QQ),<_>,cpuName,<-4>
	endm
  QQ=QQ+1
  endm
QQ=0
  rept	TOTAL_SUBKEYS-8
	irp SKn,<%QQ>
concat	<  dd Enc_SK_>,%((39-QQ) xor 1),<_>,cpuName,<-4>
	endm
  QQ=QQ+1
  endm
 endif
	irp	cby,<%($-TwoFishEncrypt_&cpuName)>	;display code size at assemble time
	  %out	--- Encrypt assembly code size == cby bytes (cpuName)
	endm
TwoFishEncrypt_&cpuName endp

;
;----------------------------------------------------------------------------------
;		Decryption
;----------------------------------------------------------------------------------
;
; use same parameters and locals as blockEncrypt_86

TwoFishDecrypt_&cpuName proc	
	pushad							;save all regs
	sub		esp,localSize			;set up local stack frame

	mov		ebp,ksPtr
	mov		edx,cipherPtr

	mov		esi,inputPtr			;is the text "in-place"?
	mov		edi,outBuffer

	mov		ecx,inputLen
	cmp		esi,edi

	mov		retVal,ecx				;save length as return value
	iff		nz						;if not, make it so
	  shr	ecx,5					;convert from bits to dwords
	 ifdif <cpuName>,<PentiumPro>
	  mov	eax,[edi]				;load some cache lines (for Pentium)
	  mov	ebx,[edi+32]
     endif
	  rep	movsd					;put the text in place
	endi

	biasEBP							;point EBP to Sbox 
	mov		al,[edx].mode			;figure out if we are in CBC mode

	cmp		al,MODE_CBC				;if so, make local copy of IV
	iff z
	  add	edx,IV32				;point edx directly to IV32
	elsef
	  xor	edx,edx					;NULL --> in ECB mode
	endi

	mov		esi,outBuffer
	mov		IVptr,edx

	SetSboxK8	cpuName
  if KEY_MODE and KM_ZERO
	mov		eax,ks.keyLen
	shr		eax,6					;divide by 64
	mov		eax,decJmpTab_&cpuName[4*eax-4]
	mov		roundJmpPtr,eax			;save dispatch address
  endif

	; --- main Decryption block loop ---
decryptLoop_&cpuName:
	Xor8	Dec,cpuName,x,[esi+8],OUTPUT_WHITEN+8
	Xor8	Dec,cpuName, ,[esi]  ,OUTPUT_WHITEN

  ifdif		<cpuName>,<PentiumPro>
	xor		ecx,ecx					;zero out high bits
   if EDX_ADJUST
	mov		edx,EDX_ADJUST
   else
    xor		edx,edx
   endif
  endif

  if KEY_MODE and KM_ZERO
	mov		roundNum,14
	jmp		roundJmpPtr				;dispatch to appropriate handler
   irp		_kSize,<256,192,128>
concat decLoop_,%(_kSize),<_>,cpuName,<:>
	RoundFunc	_kSize,Dec,cpuName,x2,x3,x0,x1,0,8
	RoundFunc	_kSize,Dec,cpuName,x0,x1,x2,x3,1,0
	sub		roundNum,2
concat <jae decLoop_>,%(_kSize),<_>,cpuName
	if _kSize ne 128
	  jmp	decDone_&cpuName
	endif
   endm
decDone_&cpuName:
  else
	Decrypt2Rounds	14,cpuName		;do rounds in reverse order
	Decrypt2Rounds	12,cpuName
	Decrypt2Rounds	10,cpuName
	Decrypt2Rounds	8,cpuName

	Decrypt2Rounds	6,cpuName
	Decrypt2Rounds	4,cpuName
	Decrypt2Rounds	2,cpuName
	Decrypt2Rounds	0,cpuName
  endif
	mov		edi,IVptr
	mov		esi,outBuffer			;remove input whitening, store plaintext

	or		edi,edi					;are we in CBC mode?
	iff nz
	  Xor8	Dec_CBC,cpuName,[esi+8],   ,INPUT_WHITEN+8,[edi+8],[edi+8]
	  Xor8	Dec_CBC,cpuName,[esi]  ,x  ,INPUT_WHITEN  ,[edi]  ,[edi]
	elsef
	  Xor8	Dec,cpuName,[esi+8],   ,INPUT_WHITEN+8
	  Xor8	Dec,cpuName,[esi]  ,x  ,INPUT_WHITEN
	endi

	add		esi,BLOCK_SIZE/8
	mov		edi,inputLen

	mov		outBuffer,esi
	sub		edi,BLOCK_SIZE

	mov		inputLen,edi			;save updated length
	ja		decryptLoop_&cpuName	;are we done? if not, go back for more

	; clean up stack and return
	add		esp,localSize
	popad							;restore regs, including retVal to eax
	ret

  if KEY_MODE and KM_ZERO
decJmpTab_&cpuName	label	dword
		dd	decLoop_128_&cpuName,decLoop_128_&cpuName
		dd	decLoop_192_&cpuName,decLoop_256_&cpuName
  endif
	irp	cby,<%($-TwoFishDecrypt_&cpuName)>	;display code size at assemble time
	  %out	--- Decrypt assembly code size == cby bytes (cpuName)
	endm
cipherProcEnd_&cpuName	label	byte

 if KEY_MODE and KM_COMPILE			;make a subkey compilation "patch" list
PatchList_Dec_&cpuName	label	dword
QQ=0
  rept	TOTAL_SUBKEYS
	irp SKn,<%QQ>
concat	<  dd Dec_SK_>,%(QQ),<_>,cpuName,<-4>
	endm
  QQ=QQ+1

⌨️ 快捷键说明

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