; Copyright (C) 2003,2006 B. Poettering
; 
; This program is free software; you can redistribute and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version. Whenever you redistribute a copy
; of this document, make sure to include the copyright and license
; agreement without modification.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
; The license text can be found here: http://www.gnu.org/licenses/gpl.txt

;                http://point-at-infinity.org/avraes/
;
; This AES implementation was written in May 2003 by B. Poettering. It is 
; published under the terms of the GNU General Public License. If you need 
; AES code, but this license is unsuitable for your project, feel free to 
; contact me: avraes AT point-at-infinity.org


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;                            RijndaelFurious
;
; This is a microcontroller implementation of the Rijndael block cipher, better
; known as AES. The target device class is Atmel's AVR, a family of very fast 
; and very powerful flash MCUs, operating at clock rates up to 16 MHz,  
; executing one instruction per clock cycle (16 MIPS). The implementation 
; given here achieves an encryption rate of about 93 kByte per second (on a 
; 16MHz MCU). The decryption performs about 30% slower than encryption (typical 
; for Rijndael).
; 
; The implemented algorithm is restricted to block and key sizes of 128 bit. 
; Larger key sizes can be obtained by altering the key scheduling code, which
; should be easy. As the cipher's state is completely kept in registers
; (which are limited in number), the block size is not that easy to enlarge.
; 
; This implementation makes extensive use of the AVR's "lpm" instruction,
; which loads data bytes from program memory at given addresses (the s-boxes 
; are realized that way). Some members of the AVR family don't offer that 
; instruction at all (e.g. AT90S1200), others only in a restricted way 
; (forcing the target register to be r0). The code below requires the least 
; restricted lpm instruction (with free choice of the target register).
; The ATmega161 devices meet the above mentioned requirements.
; 
; Statistics:
; 
; 16 MHz MCU | clock cycles | blocks per second | bytes per second
; -----------+--------------+-------------------+------------------
; encryption |    2739      |       5842        |       93465
; decryption |    3579      |       4471        |       71528
; 
; KEY SETUP TIME: 756 clock cycles
; 
; CODE SIZE
; instructions:  802 byte ( 401 words)
; sboxes:        768 byte ( 384 words) = 3 * 256 byte
; total:        1570 byte ( 785 words)
;
; RAM REQUIREMENTS
; 16 * 11 = 176 byte for each expanded key
;
;
; This source code consists of some routines and an example application, 
; which encrypts a certain plaintext and decrypts it afterwards with the
; same key. Comments in the code clarify the interaction between the key 
; expansion and the encryption/decryption routines.
;
; I encourage to read the following Rijndael-related papers/books/sites:
; [1] "The Design of Rijndael", Daemen & Rijmen, Springer, ISBN 3-540-42580-2
; [2] http://www.esat.kuleuven.ac.be/~rijmen/rijndael/
; [3] http://www.esat.kuleuven.ac.be/~rijmen/rijndael/rijndaeldocV2.zip
; [4] http://www.esat.kuleuven.ac.be/~rijmen/rijndael/atmal.zip
; [5] http://csrc.nist.gov/CryptoToolkit/aes/rijndael/
;
; [1] is *the* book about Rijndael, [2] is the official Rijndael homepage,
; [3] contains the complete Rijndael AES specification, [4] is another
; Rijndael-implementation for AVR MCUs (but much slower than this one, 
; taking 3815 clock cycles per encryption), [5] is the official NIST AES 
; site with further links.
;
; AVR and ATmega are registered trademarks by the ATMEL corporation.
; See http://www.atmel.com and http://www.atmel.com/products/avr/ for
; further details.

	
	
;;; ***************************************************************************
;;; The Rijndael cipher acts on a so-called (128 bit) "state matrix", 
;;; represented here by the 4x4 state bytes ST11-ST44. To guarantee maximum
;;; performance on AVR MCUs, these bytes are kept in registers (defaulted to
;;; the 16 low order registers r0-r15, but this may be changed if required).
;;; 
;;; The implementation makes use of four auxiliary registers (H1-H3 and I),
;;; some of which must reside in the upper registers (r16-r31). In addition
;;; ramp-registers YH:YL and ZH:ZL are used.
;;;
;;; If the context *really* requires more registers than the remaining ones, 
;;; it seems promising to move the I-register to a (fixed) ram location. 
;;; In the time crititcal routines the I-value is rarely used, thus the 
;;; speed loss obtained by dropping it from the register file is acceptible.

.include "m161def.inc"

.def ST11=r0
.def ST21=r1
.def ST31=r2
.def ST41=r3
.def ST12=r4
.def ST22=r5
.def ST32=r6
.def ST42=r7
.def ST13=r8
.def ST23=r9
.def ST33=r10
.def ST43=r11
.def ST14=r12
.def ST24=r13
.def ST34=r14
.def ST44=r15
.def H1=r16
.def H2=r17
.def H3=r18
.def I=r21y


main:	cli			; initialize stack
	ldi r31,HIGH(RAMEND)
	out SPH,r31
	ldi r31,LOW(RAMEND)
	out SPL,r31

	ldi ZH, high(key<<1)	; load key into ST11-ST44
	ldi ZL, low(key<<1)
	lpm ST11, Z+
	lpm ST21, Z+
	lpm ST31, Z+
	lpm ST41, Z+
	lpm ST12, Z+
	lpm ST22, Z+
	lpm ST32, Z+
	lpm ST42, Z+
	lpm ST13, Z+
	lpm ST23, Z+
	lpm ST33, Z+
	lpm ST43, Z+
	lpm ST14, Z+
	lpm ST24, Z+
	lpm ST34, Z+
	lpm ST44, Z+
	
	ldi YH, $00		; expand key to the memory
	ldi YL, $60		; locations $60..$60+(16*11-1)
	rcall key_expand

	ldi ZH, high(text<<1)	; load plaintext into ST11-ST44
	ldi ZL, low(text<<1)
	lpm ST11, Z+
	lpm ST21, Z+
	lpm ST31, Z+
	lpm ST41, Z+
	lpm ST12, Z+
	lpm ST22, Z+
	lpm ST32, Z+
	lpm ST42, Z+
	lpm ST13, Z+
	lpm ST23, Z+
	lpm ST33, Z+
	lpm ST43, Z+
	lpm ST14, Z+
	lpm ST24, Z+
	lpm ST34, Z+
	lpm ST44, Z+

	; now the registers ST11-ST44 contain the plaintext given below
	
	ldi YH, 0		; initialize YH:YL to
	ldi YL, 0x60		; expanded key and call
	rcall encrypt		; encryption routine

	; now the registers ST11-ST44 contain the enciphered text

	ldi YH, high($60+16*11) ; initialize YH:YL to point BEHIND
	ldi YL, low($60+16*11)	; decryption key material and
	rcall decrypt		; call decryption routine

	; now the registers ST11-ST44 contain the plaintext again

main0:	rjmp main0		; stop
	

text:
.db $32,$43,$f6,$a8,$88,$5a,$30,$8d,$31,$31,$98,$a2,$e0,$37,$07,$34
key:
.db $2b,$7e,$15,$16,$28,$ae,$d2,$a6,$ab,$f7,$15,$88,$09,$cf,$4f,$3c


;;; ***************************************************************************
;;; 
;;; KEY_EXPAND
;;; The following routine implements the Rijndael key expansion algorithm. The 
;;; caller supplies the 128 bit key in the registers ST11-ST44 and a pointer 
;;; in the YH:YL register pair. The key is expanded to the memory 
;;; positions [Y : Y+16*11-1]. Note: the key expansion is necessary for both
;;; encryption and decryption.
;;; 
;;; Parameters:
;;;     ST11-ST44:	the 128 bit key
;;;         YH:YL:	pointer to ram location
;;; Touched registers:
;;;     ST11-ST44,H1-H3,ZH,ZL,YH,YL
;;; Clock cycles:	756

key_expand:
	ldi H1, 1
	ldi H2, $1b
	ldi ZH, high(sbox<<1)
	rjmp keyexp1
keyexp0:mov ZL, ST24
	lpm H3, Z
	eor ST11, H3
	eor ST11, H1
	mov ZL, ST34
	lpm H3, Z
	eor ST21, H3
	mov ZL, ST44
	lpm H3, Z
	eor ST31, H3
	mov ZL, ST14
	lpm H3, Z
	eor ST41, H3
	eor ST12, ST11
	eor ST22, ST21
	eor ST32, ST31
	eor ST42, ST41
	eor ST13, ST12
	eor ST23, ST22
	eor ST33, ST32
	eor ST43, ST42
	eor ST14, ST13
	eor ST24, ST23
	eor ST34, ST33
	eor ST44, ST43
	lsl H1
	brcc keyexp1
	eor H1, H2
keyexp1:st Y+, ST11
	st Y+, ST21
	st Y+, ST31
	st Y+, ST41
	st Y+, ST12
	st Y+, ST22
	st Y+, ST32
	st Y+, ST42
	st Y+, ST13
	st Y+, ST23
	st Y+, ST33
	st Y+, ST43
	st Y+, ST14
	st Y+, ST24
	st Y+, ST34
	st Y+, ST44
	cpi H1, $6c
	brne keyexp0
	ret


;;; ***************************************************************************
;;; 
;;; ENCRYPT 
;;; This routine encrypts a 128 bit plaintext block (supplied in ST11-ST44), 
;;; using an expanded key given in YH:YL. The resulting 128 bit ciphertext
;;; block is stored in ST11-ST44.
;;;
;;; Parameters:
;;;         YH:YL:	pointer to expanded key
;;;         ST11-ST44:  128 bit plaintext block
;;; Touched registers:
;;;     ST11-ST44,H1,H2,H3,I,ZH,ZL,YH,YL
;;; Clock cycles:	2739
		
encrypt:
	ldi I, 10
encryp1:rcall addroundkey	; AddRoundKey
	ldi ZH, high(sbox<<1)	; SubBytes + ShiftRows
	mov ZL, ST11
	lpm ST11, Z
	mov ZL, ST12
	lpm ST12, Z
	mov ZL, ST13
	lpm ST13, Z
	mov ZL, ST14
	lpm ST14, Z
	mov H1, ST21
	mov ZL, ST22
	lpm ST21, Z
	mov ZL, ST23
	lpm ST22, Z
	mov ZL, ST24
	lpm ST23, Z
	mov ZL, H1
	lpm ST24, Z
	mov H1, ST31
	mov ZL, ST33
	lpm ST31, Z
	mov ZL, H1
	lpm ST33, Z
	mov H1, ST32
	mov ZL, ST34
	lpm ST32, Z
	mov ZL, H1
	lpm ST34, Z
	mov H1, ST44
	mov ZL, ST43
	lpm ST44, Z
	mov ZL, ST42
	lpm ST43, Z
	mov ZL, ST41
	lpm ST42, Z
	mov ZL, H1
	lpm ST41, Z
	dec I
	breq addroundkey	; AddRoundKey
	rcall mixcolumns	; MixColumns
	rjmp encryp1


;;; ***************************************************************************
;;; 
;;; ADDROUNDKEY
;;; This routine adds a round key to the state matrix (AddRoundKey). 
;;;
;;; Note: This routine is part of the encryption and decryption routines. You
;;; normally won't be interested in calling this routine directly.
;;;
;;; Parameters:
;;;         ST11-ST44:  128 bit state matrix
;;;         YH:YL:      pointer to ram location
;;; Touched registers:
;;;     ST11-ST41,H1,YH,YL

addroundkey:
	ld H1, Y+
	eor ST11, H1
	ld H1, Y+
	eor ST21, H1
	ld H1, Y+
	eor ST31, H1
	ld H1, Y+
	eor ST41, H1
	ld H1, Y+
	eor ST12, H1
	ld H1, Y+
	eor ST22, H1
	ld H1, Y+
	eor ST32, H1
	ld H1, Y+
	eor ST42, H1
	ld H1, Y+
	eor ST13, H1
	ld H1, Y+
	eor ST23, H1
	ld H1, Y+
	eor ST33, H1
	ld H1, Y+
	eor ST43, H1
	ld H1, Y+
	eor ST14, H1
	ld H1, Y+
	eor ST24, H1
	ld H1, Y+
	eor ST34, H1
	ld H1, Y+
	eor ST44, H1
	ret


;;; ***************************************************************************
;;; 
;;; MIXCOLUMNS
;;; This routine applies the MixColumns diffusion operator to the whole 
;;; state matrix. The code is used for both encryption and decryption.
;;;
;;; Note: This routine is part of the encryption and decryption routines. You
;;; normally wont be interested in calling this routine directly.
;;;
;;; Parameters:
;;;         ST11-ST44:  128 bit state matrix
;;; Touched registers:
;;;     ST11-ST41,H1,H2,H3,ZH,ZL

mixcolumns:
	ldi ZH, high(xtime<<1)
	mov H1, ST11
	eor H1, ST21
	eor H1, ST31
	eor H1, ST41
	mov H2, ST11
	mov H3, ST11
	eor H3, ST21
	mov ZL, H3
	lpm H3, Z
	eor ST11, H3
	eor ST11, H1
	mov H3, ST21
	eor H3, ST31
	mov ZL, H3
	lpm H3, Z
	eor ST21, H3
	eor ST21, H1
	mov H3, ST31
	eor H3, ST41
	mov ZL, H3
	lpm H3, Z
	eor ST31, H3
	eor ST31, H1
	mov H3, ST41
	eor H3, H2
	mov ZL, H3
	lpm H3, Z
	eor ST41, H3
	eor ST41, H1
	
	mov H1, ST12
	eor H1, ST22
	eor H1, ST32
	eor H1, ST42
	mov H2, ST12
	mov H3, ST12
	eor H3, ST22
	mov ZL, H3
	lpm H3, Z
	eor ST12, H3
	eor ST12, H1
	mov H3, ST22
	eor H3, ST32
	mov ZL, H3
	lpm H3, Z
	eor ST22, H3
	eor ST22, H1
	mov H3, ST32
	eor H3, ST42
	mov ZL, H3
	lpm H3, Z
	eor ST32, H3
	eor ST32, H1
	mov H3, ST42
	eor H3, H2
	mov ZL, H3
	lpm H3, Z
	eor ST42, H3
	eor ST42, H1
	
	mov H1, ST13
	eor H1, ST23
	eor H1, ST33
	eor H1, ST43
	mov H2, ST13
	mov H3, ST13
	eor H3, ST23
	mov ZL, H3
	lpm H3, Z
	eor ST13, H3
	eor ST13, H1
	mov H3, ST23
	eor H3, ST33
	mov ZL, H3
	lpm H3, Z
	eor ST23, H3
	eor ST23, H1
	mov H3, ST33
	eor H3, ST43
	mov ZL, H3
	lpm H3, Z
	eor ST33, H3
	eor ST33, H1
	mov H3, ST43
	eor H3, H2
	mov ZL, H3
	lpm H3, Z
	eor ST43, H3
	eor ST43, H1
	
	mov H1, ST14
	eor H1, ST24
	eor H1, ST34
	eor H1, ST44
	mov H2, ST14
	mov H3, ST14
	eor H3, ST24
	mov ZL, H3
	lpm H3, Z
	eor ST14, H3
	eor ST14, H1
	mov H3, ST24
	eor H3, ST34
	mov ZL, H3
	lpm H3, Z
	eor ST24, H3
	eor ST24, H1
	mov H3, ST34
	eor H3, ST44
	mov ZL, H3
	lpm H3, Z
	eor ST34, H3
	eor ST34, H1
	mov H3, ST44
	eor H3, H2
	mov ZL, H3
	lpm H3, Z
	eor ST44, H3
	eor ST44, H1
	ret

		
;;; ***************************************************************************
;;; 
;;; DECRYPT
;;; This routine decrypts a 128 bit ciphertext block (given in ST11-ST44), 
;;; using an expanded key supplied in the 16*11 memory locations BEFORE YH:YL
;;; (YH:YL points behind the last byte of the key material!). The resulting 128
;;; bit plaintext block is stored in ST11-ST44. 
;;;
;;; Parameters:
;;;         YH:YL:	pointer behind key
;;;         ST11-ST44:  128 bit ciphertext block
;;; Touched registers:
;;;     ST11-ST41,H1,I,ZH,ZL,YH,YL
;;; Clock cycles:	3579

decrypt:
	ldi I, 10
	sbiw YL,16
	rcall addroundkey	; AddRoundKey
	sbiw YL,32
decryp1:ldi ZH, high(isbox<<1)	; SubBytes + ShiftRows
	mov ZL, ST11
	lpm ST11, Z
	mov ZL, ST12
	lpm ST12, Z
	mov ZL, ST13
	lpm ST13, Z
	mov ZL, ST14
	lpm ST14, Z
	mov H1, ST21
	mov ZL, ST24
	lpm ST21, Z
	mov ZL, ST23
	lpm ST24, Z
	mov ZL, ST22
	lpm ST23, Z
	mov ZL, H1
	lpm ST22, Z
	mov H1, ST33
	mov ZL, ST31
	lpm ST33, Z
	mov ZL, H1
	lpm ST31, Z
	mov H1, ST34
	mov ZL, ST32
	lpm ST34, Z
	mov ZL, H1
	lpm ST32, Z
	mov H1, ST41
	mov ZL, ST42
	lpm ST41, Z
	mov ZL, ST43
	lpm ST42, Z
	mov ZL, ST44
	lpm ST43, Z
	mov ZL, H1
	lpm ST44, Z
	rcall addroundkey	; AddRoundKey
	sbiw YL,32
	dec I
	brne PC+2
	ret
	ldi ZH, high(xtime<<1)	; preprocessing to use MixColumns
	mov ZL, ST11
	eor ZL, ST31
	lpm H2, Z
	mov ZL, H2
	lpm H1, Z
	mov ZL, ST21
	eor ZL, ST41
	lpm H2, Z
	mov ZL, H2
	lpm H2, Z
	eor ST11, H1
	eor ST21, H2
	eor ST31, H1
	eor ST41, H2
	mov ZL, ST12
	eor ZL, ST32
	lpm H2, Z
	mov ZL, H2
	lpm H1, Z
	mov ZL, ST22
	eor ZL, ST42
	lpm H2, Z
	mov ZL, H2
	lpm H2, Z
	eor ST12, H1
	eor ST22, H2
	eor ST32, H1
	eor ST42, H2
	mov ZL, ST13
	eor ZL, ST33
	lpm H2, Z
	mov ZL, H2
	lpm H1, Z
	mov ZL, ST23
	eor ZL, ST43
	lpm H2, Z
	mov ZL, H2
	lpm H2, Z
	eor ST13, H1
	eor ST23, H2
	eor ST33, H1
	eor ST43, H2
	mov ZL, ST14
	eor ZL, ST34
	lpm H2, Z
	mov ZL, H2
	lpm H1, Z
	mov ZL, ST24
	eor ZL, ST44
	lpm H2, Z
	mov ZL, H2
	lpm H2, Z
	eor ST14, H1
	eor ST24, H2
	eor ST34, H1
	eor ST44, H2
	rcall mixcolumns	; MixColumns
	rjmp decryp1

;;; ***************************************************************************
;;; 
;;; S-BOX and "xtime" tables
;;; Rijndael consists of a non-linear step in its rounds (called "sbox step"), 
;;; here implemented with two hard-coded lookup tables (the sbox itself and its
;;; inverse for decryption). To provide an implementation secure against power 
;;; analysis attacks, the polynomial multiplication in the MixColumns operation 
;;; is done via an auxiliary lookup table called xtime. See [1] for details.
;;;
;;; The three tables have to be aligned to a flash position with its lower 
;;; address byte equal to $00. In assembler syntax: low(sbox<<1) == 0.
;;; To ensure the proper alignment of the sboxes, the assembler directive
;;; .ORG is used (below the sboxes are defined to begin at $800). Note, that 
;;; any other address can be used as well, as long as the lower byte is equal 
;;; to $00.
;;;
;;; The order of the sboxes is totally arbitrary. They even do not have to be
;;; allocated in adjacent memory areas.
	
.CSEG	
.ORG $800
	
sbox:
.db $63,$7c,$77,$7b,$f2,$6b,$6f,$c5,$30,$01,$67,$2b,$fe,$d7,$ab,$76 
.db $ca,$82,$c9,$7d,$fa,$59,$47,$f0,$ad,$d4,$a2,$af,$9c,$a4,$72,$c0 
.db $b7,$fd,$93,$26,$36,$3f,$f7,$cc,$34,$a5,$e5,$f1,$71,$d8,$31,$15 
.db $04,$c7,$23,$c3,$18,$96,$05,$9a,$07,$12,$80,$e2,$eb,$27,$b2,$75 
.db $09,$83,$2c,$1a,$1b,$6e,$5a,$a0,$52,$3b,$d6,$b3,$29,$e3,$2f,$84 
.db $53,$d1,$00,$ed,$20,$fc,$b1,$5b,$6a,$cb,$be,$39,$4a,$4c,$58,$cf 
.db $d0,$ef,$aa,$fb,$43,$4d,$33,$85,$45,$f9,$02,$7f,$50,$3c,$9f,$a8 
.db $51,$a3,$40,$8f,$92,$9d,$38,$f5,$bc,$b6,$da,$21,$10,$ff,$f3,$d2 
.db $cd,$0c,$13,$ec,$5f,$97,$44,$17,$c4,$a7,$7e,$3d,$64,$5d,$19,$73 
.db $60,$81,$4f,$dc,$22,$2a,$90,$88,$46,$ee,$b8,$14,$de,$5e,$0b,$db 
.db $e0,$32,$3a,$0a,$49,$06,$24,$5c,$c2,$d3,$ac,$62,$91,$95,$e4,$79 
.db $e7,$c8,$37,$6d,$8d,$d5,$4e,$a9,$6c,$56,$f4,$ea,$65,$7a,$ae,$08 
.db $ba,$78,$25,$2e,$1c,$a6,$b4,$c6,$e8,$dd,$74,$1f,$4b,$bd,$8b,$8a 
.db $70,$3e,$b5,$66,$48,$03,$f6,$0e,$61,$35,$57,$b9,$86,$c1,$1d,$9e 
.db $e1,$f8,$98,$11,$69,$d9,$8e,$94,$9b,$1e,$87,$e9,$ce,$55,$28,$df 
.db $8c,$a1,$89,$0d,$bf,$e6,$42,$68,$41,$99,$2d,$0f,$b0,$54,$bb,$16

isbox:
.db $52,$09,$6a,$d5,$30,$36,$a5,$38,$bf,$40,$a3,$9e,$81,$f3,$d7,$fb 
.db $7c,$e3,$39,$82,$9b,$2f,$ff,$87,$34,$8e,$43,$44,$c4,$de,$e9,$cb 
.db $54,$7b,$94,$32,$a6,$c2,$23,$3d,$ee,$4c,$95,$0b,$42,$fa,$c3,$4e 
.db $08,$2e,$a1,$66,$28,$d9,$24,$b2,$76,$5b,$a2,$49,$6d,$8b,$d1,$25 
.db $72,$f8,$f6,$64,$86,$68,$98,$16,$d4,$a4,$5c,$cc,$5d,$65,$b6,$92 
.db $6c,$70,$48,$50,$fd,$ed,$b9,$da,$5e,$15,$46,$57,$a7,$8d,$9d,$84 
.db $90,$d8,$ab,$00,$8c,$bc,$d3,$0a,$f7,$e4,$58,$05,$b8,$b3,$45,$06 
.db $d0,$2c,$1e,$8f,$ca,$3f,$0f,$02,$c1,$af,$bd,$03,$01,$13,$8a,$6b 
.db $3a,$91,$11,$41,$4f,$67,$dc,$ea,$97,$f2,$cf,$ce,$f0,$b4,$e6,$73 
.db $96,$ac,$74,$22,$e7,$ad,$35,$85,$e2,$f9,$37,$e8,$1c,$75,$df,$6e 
.db $47,$f1,$1a,$71,$1d,$29,$c5,$89,$6f,$b7,$62,$0e,$aa,$18,$be,$1b 
.db $fc,$56,$3e,$4b,$c6,$d2,$79,$20,$9a,$db,$c0,$fe,$78,$cd,$5a,$f4 
.db $1f,$dd,$a8,$33,$88,$07,$c7,$31,$b1,$12,$10,$59,$27,$80,$ec,$5f 
.db $60,$51,$7f,$a9,$19,$b5,$4a,$0d,$2d,$e5,$7a,$9f,$93,$c9,$9c,$ef 
.db $a0,$e0,$3b,$4d,$ae,$2a,$f5,$b0,$c8,$eb,$bb,$3c,$83,$53,$99,$61 
.db $17,$2b,$04,$7e,$ba,$77,$d6,$26,$e1,$69,$14,$63,$55,$21,$0c,$7d

xtime:
.db $00,$02,$04,$06,$08,$0a,$0c,$0e,$10,$12,$14,$16,$18,$1a,$1c,$1e
.db $20,$22,$24,$26,$28,$2a,$2c,$2e,$30,$32,$34,$36,$38,$3a,$3c,$3e
.db $40,$42,$44,$46,$48,$4a,$4c,$4e,$50,$52,$54,$56,$58,$5a,$5c,$5e
.db $60,$62,$64,$66,$68,$6a,$6c,$6e,$70,$72,$74,$76,$78,$7a,$7c,$7e
.db $80,$82,$84,$86,$88,$8a,$8c,$8e,$90,$92,$94,$96,$98,$9a,$9c,$9e
.db $a0,$a2,$a4,$a6,$a8,$aa,$ac,$ae,$b0,$b2,$b4,$b6,$b8,$ba,$bc,$be
.db $c0,$c2,$c4,$c6,$c8,$ca,$cc,$ce,$d0,$d2,$d4,$d6,$d8,$da,$dc,$de
.db $e0,$e2,$e4,$e6,$e8,$ea,$ec,$ee,$f0,$f2,$f4,$f6,$f8,$fa,$fc,$fe
.db $1b,$19,$1f,$1d,$13,$11,$17,$15,$0b,$09,$0f,$0d,$03,$01,$07,$05
.db $3b,$39,$3f,$3d,$33,$31,$37,$35,$2b,$29,$2f,$2d,$23,$21,$27,$25
.db $5b,$59,$5f,$5d,$53,$51,$57,$55,$4b,$49,$4f,$4d,$43,$41,$47,$45
.db $7b,$79,$7f,$7d,$73,$71,$77,$75,$6b,$69,$6f,$6d,$63,$61,$67,$65
.db $9b,$99,$9f,$9d,$93,$91,$97,$95,$8b,$89,$8f,$8d,$83,$81,$87,$85
.db $bb,$b9,$bf,$bd,$b3,$b1,$b7,$b5,$ab,$a9,$af,$ad,$a3,$a1,$a7,$a5
.db $db,$d9,$df,$dd,$d3,$d1,$d7,$d5,$cb,$c9,$cf,$cd,$c3,$c1,$c7,$c5
.db $fb,$f9,$ff,$fd,$f3,$f1,$f7,$f5,$eb,$e9,$ef,$ed,$e3,$e1,$e7,$e5