	LIST FIXED,C=120,F=INHX8M,N=89,P=PIC17C43,R=DEC,T=OFF,W=0,X=OFF

	ERRORLEVEL -305

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                                                            ;
; TEA17 - Tiny Encryption Algorithm                   Written by Andy Warren ;
; Version 0.1                                         9:30 pm, 30 April 1998 ;
;                                                                            ;
; (C) Fast Forward Engineering 1998                                          ;
; All Rights Reserved                                                        ;
;                                                                            ;
; TEA was developed by David Wheeler and Roger Needham at the Computer       ;
; Laboratory of Cambridge University.                                        ;
;                                                                            ;
; Written for the Microchip Technology PIC17C43 microcontroller (although    ;
; it'll run on any of the PIC17 devices).                                    ;
;                                                                            ;
; At 33 MHz, these routines will encrypt or decrypt over 12K bytes per       ;
; second.                                                                    ;
;                                                                            ;
; This program must be assembled with Microchip's MPASM assembler, version   ;
; 1.30.00 or above.                                                          ;
;                                                                            ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

INDF0	EQU	0X00
FSR0	EQU	0X01
ALUSTA	EQU	0X04
WREG	EQU	0X0A

	CBLOCK	020H

	K03		;Most-significant byte of the key.
	K02		;
	K01		;
	K00		;
			;
	K13		;
	K12		;
	K11		;
	K10		;
			;
	K23		;
	K22		;
	K21		;
	K20		;
			;
	K33		;
	K32		;
	K31		;
	K30		;Least-significant byte of the key.

	SUM3		;MSB of SUM.
	SUM2		;
	SUM1		;
	SUM0		;LSB of SUM.

	Y3		;MSB of Y.
	Y2		;
	Y1		;
	Y0		;LSB of Y.

	Z3		;MSB of Z.
	Z2		;
	Z1		;
	Z0		;LSB of Z.

	L3		;MSB of L, a temporary variable.
	L2		;
	L1		;
	L0		;LSB of L.

	R3		;MSB of R, another temporary variable.
	R2		;
	R1		;
	R0		;LSB of R.

	COUNT		;Number-of-rounds counter.

	ENDC

;
; MAIN
;

	ORG	0

START:

	MOVLW	0	;KEY = 0000 0000 0000 0000.
	MOVWF	K03	;
	MOVLW	0	;
	MOVWF	K02	;
	MOVLW	0	;
	MOVWF	K01	;
	MOVLW	0	;
	MOVWF	K00	;
	MOVLW	0	;
	MOVWF	K13	;
	MOVLW	0	;
	MOVWF	K12	;
	MOVLW	0	;
	MOVWF	K11	;
	MOVLW	0	;
	MOVWF	K10	;
	MOVLW	0	;
	MOVWF	K23	;
	MOVLW	0	;
	MOVWF	K22	;
	MOVLW	0	;
	MOVWF	K21	;
	MOVLW	0	;
	MOVWF	K20	;
	MOVLW	0	;
	MOVWF	K33	;
	MOVLW	0	;
	MOVWF	K32	;
	MOVLW	0	;
	MOVWF	K31	;
	MOVLW	0	;
	MOVWF	K30	;

	MOVLW	0	;PLAINTEXT = 0000 0000.
	MOVWF	Y3	;
	MOVLW	0	;
	MOVWF	Y2	;
	MOVLW	0	;
	MOVWF	Y1	;
	MOVLW	0	;
	MOVWF	Y0	;
	MOVLW	0	;
	MOVWF	Z3	;
	MOVLW	0	;
	MOVWF	Z2	;
	MOVLW	0	;
	MOVWF	Z1	;
	MOVLW	0	;
	MOVWF	Z0	;

; AT THIS POINT, Y3-Z0 CONTAIN THE PLAINTEXT.

	CALL	ENCODE	;ENCODE IT.

; AT THIS POINT, Y3-Z0 CONTAIN THE CIPHERTEXT.

	CALL	DECODE	;DECODE IT.

; AT THIS POINT, Y3-Z0 CONTAIN THE PLAINTEXT AGAIN.
	NOP

STOP:

	GOTO	STOP

;
; Encode Routine
;
; Routine, written in the C language, for encoding with key k[0] - k[3].
; Data in v[0] and v[1].
;
; void code(long* v, long* k)
; {
;     unsigned long y=v[0],z=v[1], sum=0,   /* set up */
;     delta=0x9e3779b9, n=32 ;             /* a key schedule constant */
;
;     while (n-- > 0)
;     {                       /* basic cycle start */
;         sum += delta ;
;
;         y += (z<<4)+k[0] ^ z+sum ^ (z>>5)+k[1] ;
;         z += (y<<4)+k[2] ^ y+sum ^ (y>>5)+k[3] ;   /* end cycle */
;     }
;
;     v[0]=y ; v[1]=z ;
; }
;

ENCODE:

	CLRF	ALUSTA		;SETUP TO POST-AUTO-DECREMENT FSR0 (AND FSR1).
	
	CLRF	SUM3		;SUM = 0.
	CLRF	SUM2		;
	CLRF	SUM1		;
	CLRF	SUM0		;

	MOVLW	32		;N = 32.
	MOVWF	COUNT		;

ELOOP:

	MOVLW	0B9H		;SUM += 0x9E3779B9.
	ADDWF	SUM0		;
				;
	MOVLW	079H		;
	ADDWFC	SUM1		;
				;
	MOVLW	037H		;
	ADDWFC	SUM2		;
				;
	MOVLW	09EH		;
	ADDWFC	SUM3		;

; y += (z<<4)+k[0] ^ z+sum ^ (z>>5)+k[1]

	CALL	ZK01SUB		;L = (Z<<4)+K[0] ^ Z+SUM ^ (Z>>5)+K[1]

	MOVFP	L0,WREG		;Y += L.
	ADDWF	Y0		;
				;
	MOVFP	L1,WREG		;
	ADDWFC	Y1		;
				;
	MOVFP	L2,WREG		;
	ADDWFC	Y2		;
				;
	MOVFP	L3,WREG		;
	ADDWFC	Y3		;

; z += (y<<4)+k[2] ^ y+sum ^ (y>>5)+k[3]

	CALL	YK23SUB		;L = (Y<<4)+K[2] ^ Y+SUM ^ (Y>>5)+K[3]

	MOVFP	L0,WREG		;Z += L.
	ADDWF	Z0		;
				;
	MOVFP	L1,WREG		;
	ADDWFC	Z1		;
				;
	MOVFP	L2,WREG		;
	ADDWFC	Z2		;
				;
	MOVFP	L3,WREG		;
	ADDWFC	Z3		;

	DECFSZ	COUNT		;DONE ALL 32 ROUNDS?
	GOTO	ELOOP		;IF NOT, LOOP BACK AND DO ANOTHER ONE.

	RETURN			;OTHERWISE, RETURN WITH CIPHERTEXT IN
				;Y3 (MSB) THROUGH Z0 (LSB).

;
; Decode Routine
;
; void decode(long* v,long* k)
; {
;     unsigned long n=32, sum, y=v[0], z=v[1],
;     delta=0x9e3779b9 ;
;
;     sum=delta<<5 ;
;                        /* start cycle */
;     while (n-- > 0)
;     {
;         z -= (y<<4)+k[2] ^ y+sum ^ (y>>5)+k[3] ;
;         y -= (z<<4)+k[0] ^ z+sum ^ (z>>5)+k[1] ;
;
;         sum -= delta ;
;     }
;                        /* end cycle */
;     v[0] = y ; v[1] = z ;
; }
;

DECODE:

	CLRF	ALUSTA		;SETUP TO POST-AUTO-DECREMENT FSR0 (AND FSR1).
	
	MOVLW	0C6H		;SUM = 0x9E3779B9 << 5.
	MOVWF	SUM3		;
	MOVLW	0EFH		;
	MOVWF	SUM2		;
	MOVLW	037H		;
	MOVWF	SUM1		;
	MOVLW	020H		;
	MOVWF	SUM0		;

	MOVLW	32		;N = 32.
	MOVWF	COUNT		;

	GOTO	SKIPSUM		;JUMP INTO THE LOOP.

DLOOP:

	MOVLW	0B9H		;SUM -= 0x9E3779B9.
	SUBWF	SUM0		;
				;
	MOVLW	079H		;
	SUBWFB	SUM1		;
				;
	MOVLW	037H		;
	SUBWFB	SUM2		;
				;
	MOVLW	09EH		;
	SUBWFB	SUM3		;

; z -= (y<<4)+k[2] ^ y+sum ^ (y>>5)+k[3]

SKIPSUM:

	CALL	YK23SUB		;L = (Y<<4)+K[2] ^ Y+SUM ^ (Y>>5)+K[3]

	MOVFP	L0,WREG		;Z -= L.
	SUBWF	Z0		;
				;
	MOVFP	L1,WREG		;
	SUBWFB	Z1		;
				;
	MOVFP	L2,WREG		;
	SUBWFB	Z2		;
				;
	MOVFP	L3,WREG		;
	SUBWFB	Z3		;

; y -= (z<<4)+k[0] ^ z+sum ^ (z>>5)+k[1]

	CALL	ZK01SUB		;L = (Z<<4)+K[0] ^ Z+SUM ^ (Z>>5)+K[1]

	MOVFP	L0,WREG		;Y -= L.
	SUBWF	Y0		;
				;
	MOVFP	L1,WREG		;
	SUBWFB	Y1		;
				;
	MOVFP	L2,WREG		;
	SUBWFB	Y2		;
				;
	MOVFP	L3,WREG		;
	SUBWFB	Y3		;

	DECFSZ	COUNT		;HAVE WE DONE ALL 32 ROUNDS?
	GOTO	DLOOP		;IF NOT, LOOP BACK AND DO ANOTHER.

	RETURN			;OTHERWISE, RETURN WITH PLAINTEXT IN
				;Y3 (MSB) THROUGH Z0 (LSB).
	
;
; SUBROUTINES COMMON TO "ENCODE" AND "DECODE".
;

ZK01SUB:

	SWAPF	Z3,W		;L = Z << 4.
	ANDLW	11110000B	;
	MOVWF	L3		;
	SWAPF	Z2,W		;
	ANDLW	00001111B	;
	IORWF	L3		;
				;
	SWAPF	Z2,W		;
	ANDLW	11110000B	;
	MOVWF	L2		;
	SWAPF	Z1,W		;
	ANDLW	00001111B	;
	IORWF	L2		;
				;
	SWAPF	Z1,W		;
	ANDLW	11110000B	;
	MOVWF	L1		;
	SWAPF	Z0,W		;
	ANDLW	00001111B	;
	IORWF	L1		;
				;
	SWAPF	Z0,W		;
	ANDLW	11110000B	;
	MOVWF	L0		;

	SWAPF	Z3,W		;R = (Z >> 5).
	RRCF	WREG		;
	ANDLW	00000111B	;
	MOVWF	R3		;
				;
	RRCF	L3,W		;
	MOVWF	R2		;
				;
	RRCF	L2,W		;
	MOVWF	R1		;
				;
	RRCF	L1,W		;
	MOVWF	R0		;

	MOVFP	K00,WREG	;L += K[0].
	ADDWF	L0		;
				;
	MOVFP	K01,WREG	;
	ADDWFC	L1		;
				;
	MOVFP	K02,WREG	;
	ADDWFC	L2		;
				;
	MOVFP	K03,WREG	;
	ADDWFC	L3		;

	MOVFP	K10,WREG	;R += K[1].
	ADDWF	R0		;
				;
	MOVFP	K11,WREG	;
	ADDWFC	R1		;
				;
	MOVFP	K12,WREG	;
	ADDWFC	R2		;
				;
	MOVFP	K13,WREG	;
	ADDWFC	R3		;

	MOVLW	Z0		;SETUP TO CALCULATE L = (Z + SUM) ^ R ^ L.

	GOTO	ADDANDXOR	;GO CALCULATE IT AND RETURN.

YK23SUB:

	SWAPF	Y3,W		;L = Y << 4.
	ANDLW	11110000B	;
	MOVWF	L3		;
	SWAPF	Y2,W		;
	ANDLW	00001111B	;
	IORWF	L3		;
				;
	SWAPF	Y2,W		;
	ANDLW	11110000B	;
	MOVWF	L2		;
	SWAPF	Y1,W		;
	ANDLW	00001111B	;
	IORWF	L2		;
				;
	SWAPF	Y1,W		;
	ANDLW	11110000B	;
	MOVWF	L1		;
	SWAPF	Y0,W		;
	ANDLW	00001111B	;
	IORWF	L1		;
				;
	SWAPF	Y0,W		;
	ANDLW	11110000B	;
	MOVWF	L0		;

	SWAPF	Y3,W		;R = (Y >> 5).
	RRCF	WREG		;
	ANDLW	00000111B	;
	MOVWF	R3		;
				;
	RRCF	L3,W		;
	MOVWF	R2		;
				;
	RRCF	L2,W		;
	MOVWF	R1		;
				;
	RRCF	L1,W		;
	MOVWF	R0		;

	MOVFP	K20,WREG	;L += K[2].
	ADDWF	L0		;
				;
	MOVFP	K21,WREG	;
	ADDWFC	L1		;
				;
	MOVFP	K22,WREG	;
	ADDWFC	L2		;
				;
	MOVFP	K23,WREG	;
	ADDWFC	L3		;

	MOVFP	K30,WREG	;R += K[3].
	ADDWF	R0		;
				;
	MOVFP	K31,WREG	;
	ADDWFC	R1		;
				;
	MOVFP	K32,WREG	;
	ADDWFC	R2		;
				;
	MOVFP	K33,WREG	;
	ADDWFC	R3		;

	MOVLW	Y0		;SETUP TO CALCULATE L = (Y + SUM) ^ R ^ L.
				;
				;FALL THROUGH TO "ADDANDXOR".

;
; ENTER WITH W CONTAINING THE ADDRESS OF THE LEAST-SIGNIFICANT BYTE OF Y OR Z.
;

ADDANDXOR:

	MOVWF	FSR0		;POINT FSR0 AT EITHER Y OR Z.

	MOVFP	INDF0,WREG	;L = (INDF0 + SUM) ^ R ^ L.
	ADDWF	SUM0,W		;
	XORWF	R0,W		;
	XORWF	L0		;
				;
	MOVFP	INDF0,WREG	;
	ADDWFC	SUM1,W		;
	XORWF	R1,W		;
	XORWF	L1		;
				;
	MOVFP	INDF0,WREG	;
	ADDWFC	SUM2,W		;
	XORWF	R2,W		;
	XORWF	L2		;
				;
	MOVFP	INDF0,WREG	;
	ADDWFC	SUM3,W		;
	XORWF	R3,W		;
	XORWF	L3		;

	RETURN			;RETURN.
	
	END

