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

📄 2fish_86.asm

📁 Assemble source code for twofish algorithm
💻 ASM
📖 第 1 页 / 共 4 页
字号:

	add		edi,esi				;complete the PHT
	GetSubkey lbl,ebx,S_INDEX+4

	add		esi,eax				;add in the round subkeys
	add		edi,ebx

	mov		eax,z2				;load z2,z3 to update them
	mov		ebx,z3
   ifdif <lbl>,<Enc>				;
	rol		eax,1				;Decryption: z2=ROL(z2,1)
	xor		ebx,edi				;half of Feistel xor

	ror		ebx,1				;Decryption: z3=ROR(z3,1)
	xor		eax,esi				;complete the Feistel xor
   else
	rol		ebx,1				;Encryption: z3=ROL(z3,1)
	xor		eax,esi				;half of Feistel xor

	ror		eax,1				;Encryption: z2=ROR(z2,1)
	xor		ebx,edi				;complete Feistel. eax,ebx=new z2,z3
   endif
  else ;--- do the compiled code thing
	mov		eax,z2				;load z2,z3 to update them
	mov		ebx,z3				;(and avoid AGI on lea opcodes below)
   ifdif <lbl>,<Enc>			;---do Decryption first
	rol		eax,1
	lea		ecx,[esi+2*edi+12345678h+4]
concat Dec_SK_,%((S_INDEX+4)/4),<_>,cpuName,< label dword>

	xor		ebx,ecx
	lea		edi,[esi+edi+12345678h]
concat Dec_SK_,%((S_INDEX+0)/4),<_>,cpuName,< label dword>

	ror		ebx,1
	xor		eax,edi
   else ;compile the encryption code
    rol		ebx,1
	lea		ecx,[esi+edi+12345678h]
concat Enc_SK_,%((S_INDEX+0)/4),<_>,cpuName,< label dword>
   
	xor		eax,ecx
	lea		edi,[esi+2*edi+12345678h+4]
concat Enc_SK_,%((S_INDEX+4)/4),<_>,cpuName,< label dword >
	
	ror		eax,1
	xor		ebx,edi
   endif
	xor		ecx,ecx
	nop							;one byte opcode, NOP here
  endif
 else ; ----------------- the Pentium Pro/II version
  if (KEY_MODE and KM_COMPILE)	;special case Pentium Pro/II compiled code
     if (R and 1)
	   RF_PPro	lbl,cpuName,c,d,a,b,R,S_INDEX
	 else
	   RF_PPro	lbl,cpuName,a,b,c,d,R,S_INDEX
     endif
  else ; !KM_COMPILE
	mov		z0,eax				;save previous round Feistel results (not on first round)
	movzx	esi,ah
	movzx	ecx,al

  if (KEY_MODE and (KM_FULL or KM_COMPILE)) eq 0
	doSbox	keySize,cpuName,esi,ecx,1,0
  endif

	mov		z1,ebx
	mov		esi,S32_1[SBS*esi]
	shr		eax,16

	mov		ecx,S32_0[SBS*ecx]
	movzx	edi,bh
	movzx	edx,bl

  if (KEY_MODE and (KM_FULL or KM_COMPILE)) eq 0
	doSbox	keySize,cpuName,edi,edx,2,1
  endif

	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 dword>
	rol		eax,1				;Decryption: z2=ROL(z2,1)
	
	lea		ecx,[esi+edi+12345678h+4]
concat Dec_SK_,%((S_INDEX+0)/4),<_>,cpuName,< label dword>
	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,< label dword>
	rol		ebx,1				;Encryption: z3=ROL(z3,1)
	
	lea		edx,[esi+2*edi+12345678h]
concat Enc_SK_,%((S_INDEX+4)/4),<_>,cpuName,< label dword>
	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
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:
	 if (cpuName eq PentiumPro) and (KEY_MODE and KM_COMPILE)
	  Xor8	Enc_CBC,cpuName,eax,ebx,   ,[esi]  ,INPUT_WHITEN,[edi]
	  Xor8	Enc_CBC,cpuName,ecx,edx,   ,[esi+8],INPUT_WHITEN+8,[edi+8]
	 else
	  Xor8	Enc_CBC,cpuName,eax,ebx,x+8,[esi+8],INPUT_WHITEN+8,[edi+8]
	  Xor8	Enc_CBC,cpuName,eax,ebx,   ,[esi]  ,INPUT_WHITEN  ,[edi]
	 endif
	elsef
Enc_ECB_&cpuName:
	  ;read plaintext block to x, add input whitening
	 if (cpuName eq PentiumPro) and (KEY_MODE and KM_COMPILE)
	  Xor8	Enc,cpuName,eax,ebx,   ,[esi]  ,INPUT_WHITEN
	  Xor8	Enc,cpuName,ecx,edx,   ,[esi+8],INPUT_WHITEN+8
	 else
	  Xor8	Enc,cpuName,eax,ebx,x+8,[esi+8],INPUT_WHITEN+8
	  Xor8	Enc,cpuName,eax,ebx,   ,[esi]  ,INPUT_WHITEN
	 endif
	endi

	;whitening/IV merged in. Now we're ready to encrypt
	;eax=x0, ebx=x1. (already loaded from INPUT_WHITEN xor)
  if cpuName ne 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
   if DO_COMPILE
	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 ;DO_COMPILE
  endif

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

  if (cpuName ne Pentium) and (KEY_MODE and KM_COMPILE)
	Xor8	Enc,cpuName,eax,ebx,[esi+8], ,OUTPUT_WHITEN+8
	Xor8	Enc,cpuName,ecx,edx,[esi]  , ,OUTPUT_WHITEN
  else
	Xor8	Enc,cpuName,eax,ebx,[esi+8],   ,OUTPUT_WHITEN+8
	Xor8	Enc,cpuName,eax,ebx,[esi]  ,x+8,OUTPUT_WHITEN
  endif

	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
	 if (cpuName ne Pentium) and (KEY_MODE and KM_COMPILE)
	  Copy8	[edi+8]
	  Copy8	[edi],[esi-16]
	 else
	  Copy8	[edi]					;if so, save new IV for next time
	  Copy8	[edi+8],[esi-8]			;[esi-8] because we just added 16 to esi
	 endif
	  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

	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:
  if (cpuName ne Pentium) and (KEY_MODE and KM_COMPILE)
	Xor8	Dec,cpuName,eax,ebx, ,[esi+8],OUTPUT_WHITEN+8
	rol eax,1						;allow initial rotate to start
	Xor8	Dec,cpuName,ecx,edx, ,[esi]  ,OUTPUT_WHITEN
  else
	Xor8	Dec,cpuName,eax,ebx,x,[esi+8],OUTPUT_WHITEN+8
	Xor8	Dec,cpuName,eax,ebx, ,[esi]  ,OUTPUT_WHITEN
  endif

  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
	 if (cpuName ne Pentium) and (KEY_MODE and KM_COMPILE)
	  Xor8	Dec_CBC,cpuName,ecx,edx,[esi+8],   ,INPUT_WHITEN+8,[edi+8],[edi+8]
	  Xor8	Dec_CBC,cpuName,eax,ebx,[esi]  ,   ,INPUT_WHITEN  ,[edi]  ,[edi]
	 else
	  Xor8	Dec_CBC,cpuName,eax,ebx,[esi+8],   ,INPUT_WHITEN+8,[edi+8],[edi+8]
	  Xor8	Dec_CBC,cpuName,eax,ebx,[esi]  ,x  ,INPUT_WHITEN  ,[edi]  ,[edi]
	 endif
	elsef
	 if (cpuName ne Pentium) and (KEY_MODE and KM_COMPILE)
	  Xor8	Dec,cpuName,ecx,edx,[esi+8],   ,INPUT_WHITEN+8
	  Xor8	Dec,cpuName,eax,ebx,[esi]  ,   ,INPUT_WHITEN
	 else
	  Xor8	Dec,cpuName,eax,ebx,[esi+8],   ,INPUT_WHITEN+8
	  Xor8	Dec,cpuName,eax,ebx,[esi]  ,x  ,INPUT_WHITEN
	 endif
	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

⌨️ 快捷键说明

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