;Skein-256-256 and ThreeFish-256 for AVR                       (C)2008 by Jan Waclawek  http://www.efton.sk
;
;free for personal/academic use
;  for commercial use please contact author: wek at efton dot sk
;
;tested with avra assembler (http://avra.sourceforge.net/ )
;  -- however, the advanced macro capabilites of avra are not used
;     so the Atmel assembler as it comes with AVR studio 
;     could be used with a bit of tweaking (renaming r00-r09 to r0-r9 
;     - in Assembler2, #define directives can be used for this)
;  -- beware, Atmel's assembler v1.74 (dec.2003) has flawed macros
;     expansion - it sometimes expands a different macro than actually used... :-(
;
;Skein-256-256 implementation parameters:
; -- uses the same resources as ThreeFish, plus 2 bytes of stack (for calling ThreeFish)
;    and 5 bytes of SRAM
; -- no fractional bits
; -- no tree mode etc., plain hash
; -- max input = 64kBytes
; -- if other output size is desired, exchange Skein256256HashInitTab
;    for the other initial vector, and take only the appropriate number
;    of bytes out of the output
; -- not optimised for size nor speed
;    -- can be sped up by unrolling, and taking into account zero bytes 
;       of most of tweak in initial part of ThreeFish
;
;
;
;ThreeFish-256 implementation parameters:
;encryption only
;uses:
; -- all the registers
; -- 73 bytes of RAM
; -- 0 bytes of stack
; -- depending on application, all of these variables are overlayable
;
;cycles:
; -- 10564 including rcall and ret
;
;code memory (FLASH/ROM) size:
; -- 2446 words = 4892 bytes
;
;
;
;Skein hash, and ThreeFish block cipher by
;  Niels Ferguson - Stefan Lucks - Bruce Schneier - Doug Whiting -
;  Mihir Bellare - Tadayoshi Kohno - Jon Callas - Jesse Walker
;Homepage:
;  http://www.schneier.com/skein.html
;
;
;



;------------------------------------------ testing --------------------------------------------------------

;of course it is irrelevant, which particular model of the AVRs we use (as long as it supports all the used instructions)
;   - this is only to have defined the RAMEND variable, and to stop some of the assemblers of screaming
.include "m8515def.inc"  

.dseg

;variables for testing
TestBackupR0:   .byte   1
TestBackupYL:   .byte   1 ;order important
TestBackupYH:   .byte   1
TestBackupZL:   .byte   1 ;
TestBackupZH:   .byte   1 ;

;register definitions for testing
.def		ZL		= r30	
.def		ZH		= r31	
.def        YL      = r28
.def        YH      = r29
.def        acc     = r16  ;pseudo-accumulator

.cseg

TestStart:

       ldi r16, high(RAMEND); Main program start
       out SPH,r16 ; Set stack pointer to top of RAM
       ldi r16, low(RAMEND)
       out SPL,r16


TestSkein:
            ldi   ZL,LOW(TestSkeinTab*2)
			ldi   ZH,HIGH(TestSkeinTab*2)
TSkeinX1:   lpm
            adiw  ZL,1
            mov   YL,r0
            lpm
            adiw  ZL,1
            mov   YH,r0
            ;as the stupid AVR assemblers don't know about byte labes for data, we need to tweak the number of data (except the exception, which is 1).
            cpi   YH,0
            brne  TSkeinX1a
            cpi   YL,1
            breq  TSkeinX1b
TSkeinX1a:  add   YL,YL
            adc   YH,YH
TSkeinX1b:
            
            call Skein            

            sts   TestBackupYL,YL
            mov   YL,r0
            sts   TestBackupYH,YH
            sts   TestBackupZL,ZL
            sts   TestBackupZH,ZH
            lds   ZL,SkeinBackupZL
            lds   ZH,SkeinBackupZH
            ;now correction for the stupid error of all AVR assemblers: they maniacally align .db to even
            sbrc  ZL,0
            adiw  ZL,1

            lpm
            adiw  ZL,1
            cp    r0,YL
            brne  TSkeinError
            lpm
            adiw  ZL,1
            cp    r0,r1
            brne  TSkeinError
            ldi   YL,2
            ldi   YH,0
TSkeinX2:   lpm
            adiw  ZL,1
            ld    r1,Y+
            cp    r0,r1
            brne  TSkeinError
            cpi   YL,28
            brne  TSkeinX2
            ldi   YL,LOW(TestBackupYL)
            ldi   YH,HIGH(TestBackupYH)
TSkeinX3:   lpm
            adiw  ZL,1
            ld    r1,Y+
            cp    r0,r1
            brne  TSkeinError
            cpi   YL,LOW(TestBackupYL+4)
            brne  TSkeinX3
            cpi   ZL,LOW(TestSkeinTabEnd*2)
            brne  TSkeinX1
            cpi   ZH,HIGH(TestSkeinTabEnd*2)
            brne  TSkeinX1
TSkeinOK:   rjmp  TestThreeFish
TSkeinError: rjmp Error




TestThreeFish:


            ldi   ZL,LOW(TestThreeFishTab*2)
			ldi   ZH,HIGH(TestThreeFishTab*2)
TTFX1:
			ldi   YL,LOW(Tweak)
			ldi   YH,HIGH(Tweak)
TTFX2:      lpm
            st    Y+,R0
            adiw  ZL,1
			cpi   YL,LOW(Tweak+2*WORDSIZE)
			brne  TTFX2

			ldi   YL,LOW(Key)
			ldi   YH,HIGH(Key)
TTFX3:      lpm
            adiw  ZL,1
            st    Y+,R0
			cpi   YL,LOW(Key+DATASIZE*WORDSIZE)
			brne  TTFX3

            lpm  
            sts   TestBackupR0, r0
            adiw  ZL,1
			ldi   YL,LOW(1) 
			ldi   YH,HIGH(1)
TTFX4:      lpm
            adiw  ZL,1
            st    Y+,R0
			cpi   YL,28  ;LOW(YL)
			brne  TTFX4
            lpm  
            adiw  ZL,1
            mov   YL,r0
            lpm  
            adiw  ZL,1
            mov   YH,r0
            lpm  
            adiw  ZL,1
            sts   TestBackupZL,r0
            lpm
            adiw  ZL,1
            sts   TestBackupZH,ZH
            mov   ZH,r0
            lds   r0,TestBackupZL
            sts   TestBackupZL,ZL
            mov   ZL,r0
            lds   r0,TestBackupR0
            
            call ThreeFish

            sts   TestBackupR0,r1
            mov   r1,r0
            lds   r0,TestBackupZL
            sts   TestBackupZL,ZL
            mov   ZL,r0
            lds   r0,TestBackupZH
            sts   TestBackupZH,ZH
            mov   ZH,r0
            lpm
            adiw  ZL,1
            cp    r0,r1
            brne  Error
            lds   r1,TestBackupR0
            lpm
            adiw  ZL,1
            cp    r0,r1
            brne  Error
            sts   TestBackupYL,YL
            sts   TestBackupYH,YH
			ldi   YL,LOW(2)         
			ldi   YH,HIGH(2)
TTFX5:      lpm  
            adiw  ZL,1
            ld    r1,Y+
            cp    r0,r1
            brne  Error
            cpi   YL,28  ;LOW(YL)
            brne  TTFX5
            ldi   YL,LOW(TestBackupYL) 
			ldi   YH,HIGH(TestBackupYH)
TTFX6:      lpm  
            adiw  ZL,1
            ld    r1,Y+
            cp    r0,r1
            brne  Error
            cpi   YL,LOW(TestBackupYL+4)
            brne  TTFX6

            cpi   ZL,LOW(2*TestThreeFishTabEnd)
            brne  TTFContinue
            cpi   ZH,HIGH(2*TestThreeFishTabEnd)
            brne  TTFContinue
            rjmp  TTFOK
TTFContinue:
            rjmp  TTFX1

TTFOK:
Stop:       rjmp  Stop
Error:      rjmp  Error




;----------------------------------------------------   tables for testing -----------------------------------------------
           
TestSkeinTab:
             .dw   TestSkeinTabResult1-TestSkeinTabMessagedata1
TestSkeinTabMessagedata1:
             .db   0xFF
TestSkeinTabResult1:
             .db   0xA4,0x7B,0xE7,0x1A,0x18,0x5B,0xA0,0xAF,0x82,0x0B,0x3C,0xE8,0x45,0xA3,0xD3,0x5A
             .db   0x80,0xEC,0x64,0xF9,0x6A,0x0D,0x6A,0x36,0xE3,0xF5,0x36,0x36,0x24,0xD8,0xA0,0x91

             .dw   TestSkeinTabResult2-TestSkeinTabMessagedata2
TestSkeinTabMessagedata2:
             .db   0xFF,0xFE,0xFD,0xFC,0xFB,0xFA,0xF9,0xF8,0xF7,0xF6,0xF5,0xF4,0xF3,0xF2,0xF1,0xF0
             .db   0xEF,0xEE,0xED,0xEC,0xEB,0xEA,0xE9,0xE8,0xE7,0xE6,0xE5,0xE4,0xE3,0xE2,0xE1,0xE0
TestSkeinTabResult2:
             .db   0xCC,0x2D,0xA8,0x2F,0x39,0x73,0xC2,0xF7,0xA8,0xCE,0xD0,0xBB,0xB5,0x4A,0xA0,0x28
             .db   0xEC,0xAF,0x6B,0x59,0x11,0x62,0x8D,0x0F,0xFA,0xBB,0x20,0x08,0xE4,0x11,0xD1,0x71

             .dw   TestSkeinTabResult3-TestSkeinTabMessagedata3
TestSkeinTabMessagedata3:
             .db   0xFF,0xFE,0xFD,0xFC,0xFB,0xFA,0xF9,0xF8,0xF7,0xF6,0xF5,0xF4,0xF3,0xF2,0xF1,0xF0
             .db   0xEF,0xEE,0xED,0xEC,0xEB,0xEA,0xE9,0xE8,0xE7,0xE6,0xE5,0xE4,0xE3,0xE2,0xE1,0xE0
             .db   0xDF,0xDE,0xDD,0xDC,0xDB,0xDA,0xD9,0xD8,0xD7,0xD6,0xD5,0xD4,0xD3,0xD2,0xD1,0xD0
             .db   0xCF,0xCE,0xCD,0xCC,0xCB,0xCA,0xC9,0xC8,0xC7,0xC6,0xC5,0xC4,0xC3,0xC2,0xC1,0xC0
TestSkeinTabResult3:
             .db   0xFA,0x1A,0x76,0x2B,0x6B,0x1C,0x72,0xB7,0x0D,0x52,0x92,0x63,0x53,0xE1,0x0E,0xB8
             .db   0xFB,0x0E,0xDD,0x73,0x13,0xDA,0x20,0xA2,0x41,0x31,0x80,0xB8,0xE2,0x89,0xB8,0x72


;Skein-256:   256-bit hash, msgLen =     0 bits, data = 'zero'

             .dw   TestSkeinTabResult4-TestSkeinTabMessagedata4
TestSkeinTabMessagedata4:
TestSkeinTabResult4:
             .db   0xBC,0x27,0x63,0xF7,0x07,0xE2,0x62,0xB8,0x0E,0x03,0x13,0x79,0x15,0x43,0xA7,0xAB
             .db   0x0A,0x4B,0x6C,0xD0,0x83,0x27,0x0A,0xFB,0x2F,0xCE,0x42,0x72,0xE1,0xBB,0x0A,0xA9


;Skein-256:   256-bit hash, msgLen =     8 bits, data = 'zero'

             .dw   TestSkeinTabResult5-TestSkeinTabMessagedata5
TestSkeinTabMessagedata5:
             .db   0x00
TestSkeinTabResult5:
             .db   0xA6,0xCA,0xBF,0x2D,0xB0,0x1A,0x6F,0x27,0x42,0x40,0x42,0x93,0x64,0x39,0x92,0x8C
             .db   0xA8,0x38,0x54,0x93,0x52,0x94,0xDF,0x98,0x19,0xE7,0xC4,0xC6,0x61,0xFC,0x31,0x9F


;Skein-256:   256-bit hash, msgLen =    32 bits, data = 'zero'

             .dw   TestSkeinTabResult6-TestSkeinTabMessagedata6
TestSkeinTabMessagedata6:
             .db   0x00,0x00,0x00,0x00
TestSkeinTabResult6:
             .db   0xA8,0x17,0x45,0xA0,0xD1,0x5D,0x10,0x32,0x4A,0x44,0x50,0x69,0x41,0x23,0xED,0x63
             .db   0x2A,0xE3,0x6A,0x69,0x30,0x8B,0x85,0x12,0xF5,0x6E,0xA5,0x3C,0x4B,0x74,0xD1,0x18


;Skein-256:   256-bit hash, msgLen =    64 bits, data = 'zero'
             .dw   TestSkeinTabResult7-TestSkeinTabMessagedata7
TestSkeinTabMessagedata7:
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
TestSkeinTabResult7:
             .db   0x70,0x03,0x5E,0xDF,0x23,0x5A,0x44,0x9C,0x43,0x36,0xB8,0x22,0x2D,0xF8,0x89,0xFB
             .db   0x01,0x7C,0xFA,0x70,0x35,0x77,0x0D,0x0F,0xD9,0x8F,0x67,0x87,0xAC,0xC9,0x7B,0x6C


;Skein-256:   256-bit hash, msgLen =   128 bits, data = 'zero'

             .dw   TestSkeinTabResult8-TestSkeinTabMessagedata8
TestSkeinTabMessagedata8:
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
TestSkeinTabResult8:
             .db   0xF6,0xC8,0x39,0x70,0xCF,0x27,0xD7,0xC1,0xC6,0xFB,0xA8,0x8B,0xD8,0xDB,0xDC,0x6E
             .db   0x73,0x9E,0xEC,0x4F,0x74,0x54,0xAE,0xF0,0x68,0x3A,0xC5,0x2A,0x2A,0xE2,0x8D,0x4E


;Skein-256:   256-bit hash, msgLen =   192 bits, data = 'zero'

             .dw   TestSkeinTabResult9-TestSkeinTabMessagedata9
TestSkeinTabMessagedata9:
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
TestSkeinTabResult9:
             .db   0x5A,0xCE,0xBD,0x60,0xD8,0x8C,0x56,0xEF,0x3E,0x22,0x4A,0x53,0x5E,0xB1,0xB8,0x83
             .db   0x14,0xCC,0xA8,0x55,0xF4,0xAE,0x11,0x4A,0x71,0x33,0x86,0x49,0xFA,0x1C,0x23,0xBD



;Skein-256:   256-bit hash, msgLen =   256 bits, data = 'zero'

             .dw   TestSkeinTabResult10-TestSkeinTabMessagedata10
TestSkeinTabMessagedata10:
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
TestSkeinTabResult10:
             .db   0xBD,0x26,0x91,0xB6,0x8F,0x9B,0xE3,0x3E,0x60,0x89,0xDA,0x56,0x0D,0x7C,0x51,0x9D
             .db   0xC2,0x44,0x53,0x3D,0xA7,0x1E,0x7B,0x3B,0x11,0xE2,0x94,0xA1,0x5E,0x6A,0x6C,0x30


;Skein-256:   256-bit hash, msgLen =   384 bits, data = 'zero'

             .dw   TestSkeinTabResult11-TestSkeinTabMessagedata11
TestSkeinTabMessagedata11:
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
TestSkeinTabResult11:
             .db   0x4E,0x0E,0x2E,0x06,0xC1,0xDC,0xAF,0xB5,0x93,0xEA,0x0E,0x38,0xDF,0x44,0xE2,0xE0
             .db   0x8F,0x14,0x05,0xA4,0xC8,0x3B,0xB7,0xE3,0x60,0xB0,0x97,0x15,0xDA,0x9D,0x33,0xB0


;Skein-256:   256-bit hash, msgLen =   512 bits, data = 'zero'

             .dw   TestSkeinTabResult12-TestSkeinTabMessagedata12
TestSkeinTabMessagedata12:
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
TestSkeinTabResult12:
             .db   0xB7,0xCC,0x86,0x69,0x7D,0xC3,0x72,0x0C,0xB6,0xD0,0x38,0x06,0x77,0x0B,0x38,0x86
             .db   0x5C,0x5F,0x9C,0xFE,0x5A,0x27,0xFD,0xD3,0xF9,0xA7,0xE6,0xD4,0xE0,0xA4,0x35,0x8B

;Skein-256:   256-bit hash, msgLen =   768 bits, data = 'zero'

             .dw   TestSkeinTabResult13-TestSkeinTabMessagedata13
TestSkeinTabMessagedata13:
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
TestSkeinTabResult13:
             .db   0x06,0xF8,0x74,0x86,0x64,0x2A,0xF0,0x93,0x41,0xA1,0xA8,0x19,0x06,0xE0,0x8E,0x6A
             .db   0x40,0x7C,0x5A,0x50,0x14,0xF1,0x21,0x61,0x94,0x22,0x6F,0xD4,0xE9,0x29,0x9D,0xD7

;Skein-256:   256-bit hash, msgLen =  1024 bits, data = 'zero'

             .dw   TestSkeinTabResult14-TestSkeinTabMessagedata14
TestSkeinTabMessagedata14:
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
TestSkeinTabResult14:
             .db   0xDB,0x65,0x89,0x5E,0xB2,0x11,0xFB,0x9C,0xE3,0xB6,0x0B,0x02,0x30,0xC2,0xFD,0xA1
             .db   0xEF,0xBA,0x3B,0x6E,0xDC,0x23,0xE9,0x27,0xC6,0x0B,0x24,0x74,0x1E,0x42,0x39,0xC9

;Skein-256:   256-bit hash, msgLen =  2048 bits, data = 'zero'

             .dw   TestSkeinTabResult15-TestSkeinTabMessagedata15
TestSkeinTabMessagedata15:
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
             .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
TestSkeinTabResult15:
             .db   0xC2,0xB3,0x00,0x31,0x4C,0x0E,0x66,0xDC,0x3E,0x2A,0x44,0x29,0xB1,0xF6,0x3D,0xF3
             .db   0xC2,0xE6,0x5C,0x88,0x65,0xE7,0xC3,0x85,0xBA,0xFE,0xA4,0x2C,0x9E,0x2C,0x6F,0x42

     


;Skein-256:   256-bit hash, msgLen =     0 bits, data = 'incrementing'

             .dw   TestSkeinTabResult16-TestSkeinTabMessagedata16
TestSkeinTabMessagedata16:
TestSkeinTabResult16:
             .db   0xBC,0x27,0x63,0xF7,0x07,0xE2,0x62,0xB8,0x0E,0x03,0x13,0x79,0x15,0x43,0xA7,0xAB
             .db   0x0A,0x4B,0x6C,0xD0,0x83,0x27,0x0A,0xFB,0x2F,0xCE,0x42,0x72,0xE1,0xBB,0x0A,0xA9

;Skein-256:   256-bit hash, msgLen =     8 bits, data = 'incrementing'

             .dw   TestSkeinTabResult17-TestSkeinTabMessagedata17
TestSkeinTabMessagedata17:
             .db   0xFF
TestSkeinTabResult17:
             .db   0xA4,0x7B,0xE7,0x1A,0x18,0x5B,0xA0,0xAF,0x82,0x0B,0x3C,0xE8,0x45,0xA3,0xD3,0x5A
             .db   0x80,0xEC,0x64,0xF9,0x6A,0x0D,0x6A,0x36,0xE3,0xF5,0x36,0x36,0x24,0xD8,0xA0,0x91


;Skein-256:   256-bit hash, msgLen =    32 bits, data = 'incrementing'

             .dw   TestSkeinTabResult18-TestSkeinTabMessagedata18
TestSkeinTabMessagedata18:
             .db   0xFF,0xFE,0xFD,0xFC
TestSkeinTabResult18:
             .db   0xA6,0x1E,0x60,0x21,0xBF,0xE2,0x47,0xD7,0x5A,0xA6,0xC9,0x02,0x70,0x21,0x75,0xCF
             .db   0xD4,0xDE,0x05,0xB4,0x92,0xAA,0x2D,0x39,0x9D,0xAC,0x3F,0x66,0xB0,0x2E,0xA9,0x3B


;Skein-256:   256-bit hash, msgLen =    64 bits, data = 'incrementing'
             .dw   TestSkeinTabResult19-TestSkeinTabMessagedata19
TestSkeinTabMessagedata19:
             .db   0xFF,0xFE,0xFD,0xFC,0xFB,0xFA,0xF9,0xF8
TestSkeinTabResult19:
             .db   0x97,0x15,0x51,0x7C,0xAF,0xAC,0x81,0x0B,0xC7,0x4A,0x0F,0xCA,0x37,0x9E,0xDB,0x11
             .db   0x95,0xEF,0xB0,0xED,0x50,0xE8,0x89,0x53,0xAC,0xD1,0x39,0x0F,0x50,0x8B,0x94,0xAB


;Skein-256:   256-bit hash, msgLen =   128 bits, data = 'incrementing'
             .dw   TestSkeinTabResult20-TestSkeinTabMessagedata20
TestSkeinTabMessagedata20:
             .db   0xFF,0xFE,0xFD,0xFC,0xFB,0xFA,0xF9,0xF8,0xF7,0xF6,0xF5,0xF4,0xF3,0xF2,0xF1,0xF0
TestSkeinTabResult20:
             .db   0x34,0x60,0xD8,0x0F,0x1B,0xE5,0x43,0xD0,0x7F,0x2E,0x75,0xC2,0x5B,0xE2,0x73,0x3C
             .db   0xCD,0x75,0xF5,0x66,0xB1,0x98,0xF0,0x2F,0xDD,0xC9,0x1C,0xE4,0xF2,0xD4,0x8B,0xD2


;Skein-256:   256-bit hash, msgLen =   192 bits, data = 'incrementing'

             .dw   TestSkeinTabResult21-TestSkeinTabMessagedata21
TestSkeinTabMessagedata21:
             .db   0xFF,0xFE,0xFD,0xFC,0xFB,0xFA,0xF9,0xF8,0xF7,0xF6,0xF5,0xF4,0xF3,0xF2,0xF1,0xF0
             .db   0xEF,0xEE,0xED,0xEC,0xEB,0xEA,0xE9,0xE8
TestSkeinTabResult21:
             .db   0xA6,0xB2,0x18,0x17,0xBA,0x50,0xC8,0xE6,0x75,0x5B,0x24,0x8D,0x76,0xAA,0x31,0x0F
             .db   0xB8,0x6A,0xAE,0x69,0x35,0x57,0x79,0x9A,0x79,0x5A,0x54,0x91,0x12,0x84,0xFD,0xC0


;Skein-256:   256-bit hash, msgLen =   256 bits, data = 'incrementing'

             .dw   TestSkeinTabResult22-TestSkeinTabMessagedata22
TestSkeinTabMessagedata22:
             .db   0xFF,0xFE,0xFD,0xFC,0xFB,0xFA,0xF9,0xF8,0xF7,0xF6,0xF5,0xF4,0xF3,0xF2,0xF1,0xF0
             .db   0xEF,0xEE,0xED,0xEC,0xEB,0xEA,0xE9,0xE8,0xE7,0xE6,0xE5,0xE4,0xE3,0xE2,0xE1,0xE0
TestSkeinTabResult22:
             .db   0xCC,0x2D,0xA8,0x2F,0x39,0x73,0xC2,0xF7,0xA8,0xCE,0xD0,0xBB,0xB5,0x4A,0xA0,0x28
             .db   0xEC,0xAF,0x6B,0x59,0x11,0x62,0x8D,0x0F,0xFA,0xBB,0x20,0x08,0xE4,0x11,0xD1,0x71


;Skein-256:   256-bit hash, msgLen =   384 bits, data = 'incrementing'

             .dw   TestSkeinTabResult23-TestSkeinTabMessagedata23
TestSkeinTabMessagedata23:
             .db   0xFF,0xFE,0xFD,0xFC,0xFB,0xFA,0xF9,0xF8,0xF7,0xF6,0xF5,0xF4,0xF3,0xF2,0xF1,0xF0
             .db   0xEF,0xEE,0xED,0xEC,0xEB,0xEA,0xE9,0xE8,0xE7,0xE6,0xE5,0xE4,0xE3,0xE2,0xE1,0xE0
             .db   0xDF,0xDE,0xDD,0xDC,0xDB,0xDA,0xD9,0xD8,0xD7,0xD6,0xD5,0xD4,0xD3,0xD2,0xD1,0xD0
TestSkeinTabResult23:
             .db   0xAF,0x11,0x2F,0xAE,0x4A,0xA8,0x40,0xE2,0x7E,0x62,0x81,0x8D,0x06,0x61,0x04,0x75
             .db   0xD9,0x56,0x8A,0x84,0x34,0x59,0x5D,0x49,0xD6,0x2F,0x86,0x47,0xAA,0x6C,0x19,0x27


;Skein-256:   256-bit hash, msgLen =   512 bits, data = 'incrementing'

             .dw   TestSkeinTabResult24-TestSkeinTabMessagedata24
TestSkeinTabMessagedata24:
             .db   0xFF,0xFE,0xFD,0xFC,0xFB,0xFA,0xF9,0xF8,0xF7,0xF6,0xF5,0xF4,0xF3,0xF2,0xF1,0xF0
             .db   0xEF,0xEE,0xED,0xEC,0xEB,0xEA,0xE9,0xE8,0xE7,0xE6,0xE5,0xE4,0xE3,0xE2,0xE1,0xE0
             .db   0xDF,0xDE,0xDD,0xDC,0xDB,0xDA,0xD9,0xD8,0xD7,0xD6,0xD5,0xD4,0xD3,0xD2,0xD1,0xD0
             .db   0xCF,0xCE,0xCD,0xCC,0xCB,0xCA,0xC9,0xC8,0xC7,0xC6,0xC5,0xC4,0xC3,0xC2,0xC1,0xC0
TestSkeinTabResult24:
             .db   0xFA,0x1A,0x76,0x2B,0x6B,0x1C,0x72,0xB7,0x0D,0x52,0x92,0x63,0x53,0xE1,0x0E,0xB8
             .db   0xFB,0x0E,0xDD,0x73,0x13,0xDA,0x20,0xA2,0x41,0x31,0x80,0xB8,0xE2,0x89,0xB8,0x72


;Skein-256:   256-bit hash, msgLen =   768 bits, data = 'incrementing'

             .dw   TestSkeinTabResult25-TestSkeinTabMessagedata25
TestSkeinTabMessagedata25:
             .db   0xFF,0xFE,0xFD,0xFC,0xFB,0xFA,0xF9,0xF8,0xF7,0xF6,0xF5,0xF4,0xF3,0xF2,0xF1,0xF0
             .db   0xEF,0xEE,0xED,0xEC,0xEB,0xEA,0xE9,0xE8,0xE7,0xE6,0xE5,0xE4,0xE3,0xE2,0xE1,0xE0
             .db   0xDF,0xDE,0xDD,0xDC,0xDB,0xDA,0xD9,0xD8,0xD7,0xD6,0xD5,0xD4,0xD3,0xD2,0xD1,0xD0
             .db   0xCF,0xCE,0xCD,0xCC,0xCB,0xCA,0xC9,0xC8,0xC7,0xC6,0xC5,0xC4,0xC3,0xC2,0xC1,0xC0
             .db   0xBF,0xBE,0xBD,0xBC,0xBB,0xBA,0xB9,0xB8,0xB7,0xB6,0xB5,0xB4,0xB3,0xB2,0xB1,0xB0
             .db   0xAF,0xAE,0xAD,0xAC,0xAB,0xAA,0xA9,0xA8,0xA7,0xA6,0xA5,0xA4,0xA3,0xA2,0xA1,0xA0
TestSkeinTabResult25:
             .db   0x30,0x70,0x95,0xDF,0x4A,0x0D,0xF7,0x92,0xE1,0xAB,0x68,0x6F,0xF6,0x5C,0x16,0xE1
             .db   0xF6,0x2B,0xB3,0x60,0x41,0xDE,0x88,0xEC,0x26,0xD4,0x83,0x5F,0x36,0x04,0x7F,0x4F


;Skein-256:   256-bit hash, msgLen =  1024 bits, data = 'incrementing'

             .dw   TestSkeinTabResult26-TestSkeinTabMessagedata26
TestSkeinTabMessagedata26:
             .db   0xFF,0xFE,0xFD,0xFC,0xFB,0xFA,0xF9,0xF8,0xF7,0xF6,0xF5,0xF4,0xF3,0xF2,0xF1,0xF0
             .db   0xEF,0xEE,0xED,0xEC,0xEB,0xEA,0xE9,0xE8,0xE7,0xE6,0xE5,0xE4,0xE3,0xE2,0xE1,0xE0
             .db   0xDF,0xDE,0xDD,0xDC,0xDB,0xDA,0xD9,0xD8,0xD7,0xD6,0xD5,0xD4,0xD3,0xD2,0xD1,0xD0
             .db   0xCF,0xCE,0xCD,0xCC,0xCB,0xCA,0xC9,0xC8,0xC7,0xC6,0xC5,0xC4,0xC3,0xC2,0xC1,0xC0
             .db   0xBF,0xBE,0xBD,0xBC,0xBB,0xBA,0xB9,0xB8,0xB7,0xB6,0xB5,0xB4,0xB3,0xB2,0xB1,0xB0
             .db   0xAF,0xAE,0xAD,0xAC,0xAB,0xAA,0xA9,0xA8,0xA7,0xA6,0xA5,0xA4,0xA3,0xA2,0xA1,0xA0
             .db   0x9F,0x9E,0x9D,0x9C,0x9B,0x9A,0x99,0x98,0x97,0x96,0x95,0x94,0x93,0x92,0x91,0x90
             .db   0x8F,0x8E,0x8D,0x8C,0x8B,0x8A,0x89,0x88,0x87,0x86,0x85,0x84,0x83,0x82,0x81,0x80
TestSkeinTabResult26:
             .db   0xD5,0x0E,0x55,0xEB,0x01,0xB8,0xB5,0xB6,0x4A,0xAE,0xBA,0x67,0x3C,0x27,0x6A,0x0D
             .db   0x49,0x81,0x60,0x7D,0xDB,0x20,0x9B,0x83,0xA5,0xE0,0xE2,0x61,0xCC,0x98,0x30,0x34


;Skein-256:   256-bit hash, msgLen =  2048 bits, data = 'incrementing'

             .dw   TestSkeinTabResult27-TestSkeinTabMessagedata27
TestSkeinTabMessagedata27:
             .db   0xFF,0xFE,0xFD,0xFC,0xFB,0xFA,0xF9,0xF8,0xF7,0xF6,0xF5,0xF4,0xF3,0xF2,0xF1,0xF0
             .db   0xEF,0xEE,0xED,0xEC,0xEB,0xEA,0xE9,0xE8,0xE7,0xE6,0xE5,0xE4,0xE3,0xE2,0xE1,0xE0
             .db   0xDF,0xDE,0xDD,0xDC,0xDB,0xDA,0xD9,0xD8,0xD7,0xD6,0xD5,0xD4,0xD3,0xD2,0xD1,0xD0
             .db   0xCF,0xCE,0xCD,0xCC,0xCB,0xCA,0xC9,0xC8,0xC7,0xC6,0xC5,0xC4,0xC3,0xC2,0xC1,0xC0
             .db   0xBF,0xBE,0xBD,0xBC,0xBB,0xBA,0xB9,0xB8,0xB7,0xB6,0xB5,0xB4,0xB3,0xB2,0xB1,0xB0
             .db   0xAF,0xAE,0xAD,0xAC,0xAB,0xAA,0xA9,0xA8,0xA7,0xA6,0xA5,0xA4,0xA3,0xA2,0xA1,0xA0
             .db   0x9F,0x9E,0x9D,0x9C,0x9B,0x9A,0x99,0x98,0x97,0x96,0x95,0x94,0x93,0x92,0x91,0x90
             .db   0x8F,0x8E,0x8D,0x8C,0x8B,0x8A,0x89,0x88,0x87,0x86,0x85,0x84,0x83,0x82,0x81,0x80
             .db   0x7F,0x7E,0x7D,0x7C,0x7B,0x7A,0x79,0x78,0x77,0x76,0x75,0x74,0x73,0x72,0x71,0x70
             .db   0x6F,0x6E,0x6D,0x6C,0x6B,0x6A,0x69,0x68,0x67,0x66,0x65,0x64,0x63,0x62,0x61,0x60
             .db   0x5F,0x5E,0x5D,0x5C,0x5B,0x5A,0x59,0x58,0x57,0x56,0x55,0x54,0x53,0x52,0x51,0x50
             .db   0x4F,0x4E,0x4D,0x4C,0x4B,0x4A,0x49,0x48,0x47,0x46,0x45,0x44,0x43,0x42,0x41,0x40
             .db   0x3F,0x3E,0x3D,0x3C,0x3B,0x3A,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30
             .db   0x2F,0x2E,0x2D,0x2C,0x2B,0x2A,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20
             .db   0x1F,0x1E,0x1D,0x1C,0x1B,0x1A,0x19,0x18,0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10
             .db   0x0F,0x0E,0x0D,0x0C,0x0B,0x0A,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00
TestSkeinTabResult27:
             .db   0x12,0xA3,0x24,0x5F,0x2E,0xF8,0x87,0x99,0xB9,0xE2,0x04,0x80,0x21,0x65,0xDC,0x75
             .db   0xFF,0x36,0x5B,0xE4,0xF8,0x64,0xFE,0x1D,0xAC,0x0D,0x47,0xB6,0xF2,0x5B,0xD5,0x46



;Skein-256:   256-bit hash, msgLen =     0 bits, data = 'random'

             .dw   TestSkeinTabResult28-TestSkeinTabMessagedata28
TestSkeinTabMessagedata28:
TestSkeinTabResult28:
             .db   0xBC,0x27,0x63,0xF7,0x07,0xE2,0x62,0xB8,0x0E,0x03,0x13,0x79,0x15,0x43,0xA7,0xAB
             .db   0x0A,0x4B,0x6C,0xD0,0x83,0x27,0x0A,0xFB,0x2F,0xCE,0x42,0x72,0xE1,0xBB,0x0A,0xA9


;Skein-256:   256-bit hash, msgLen =     8 bits, data = 'random'

             .dw   TestSkeinTabResult29-TestSkeinTabMessagedata29
TestSkeinTabMessagedata29:
             .db   0xFB
TestSkeinTabResult29:
             .db   0x5B,0xE9,0xA2,0x10,0xAC,0x91,0x7F,0x49,0xA5,0x80,0x54,0x45,0xDD,0x97,0xBB,0x56
             .db   0xF0,0x4F,0x36,0x63,0x99,0xCF,0x0A,0xCD,0xE4,0x22,0xFF,0x25,0x3A,0x3F,0x49,0xFB


;Skein-256:   256-bit hash, msgLen =    32 bits, data = 'random'

             .dw   TestSkeinTabResult30-TestSkeinTabMessagedata30
TestSkeinTabMessagedata30:
             .db   0xFB,0xD1,0x7C,0x26
TestSkeinTabResult30:
             .db   0xBA,0x4D,0x44,0x62,0x35,0x18,0xD9,0x94,0xAD,0x01,0x9E,0xBD,0xB5,0x99,0x44,0xA9
             .db   0xFB,0x46,0x17,0xD8,0x59,0xD9,0x2E,0x33,0x82,0x88,0x9D,0xA4,0x4C,0xB8,0x05,0xA2


;Skein-256:   256-bit hash, msgLen =    64 bits, data = 'random'

             .dw   TestSkeinTabResult31-TestSkeinTabMessagedata31
TestSkeinTabMessagedata31:
             .db   0xFB,0xD1,0x7C,0x26,0xB6,0x1A,0x82,0xE1
TestSkeinTabResult31:
             .db   0xD5,0x86,0x2B,0xB1,0x46,0x24,0x2F,0xEB,0x69,0xDA,0x42,0x73,0xCF,0x20,0x34,0xEF
             .db   0xE2,0x2B,0xDB,0x7B,0x61,0x2E,0x4D,0xE7,0x2D,0x71,0x87,0x84,0x97,0x37,0x6B,0xF9


;Skein-256:   256-bit hash, msgLen =   128 bits, data = 'random'

             .dw   TestSkeinTabResult32-TestSkeinTabMessagedata32
TestSkeinTabMessagedata32:
             .db   0xFB,0xD1,0x7C,0x26,0xB6,0x1A,0x82,0xE1,0x2E,0x12,0x5F,0x0D,0x45,0x9B,0x96,0xC9
TestSkeinTabResult32:
             .db   0xBB,0xE5,0xC3,0x57,0xEC,0x9D,0x42,0x0E,0xE6,0x23,0x76,0xE7,0x9D,0x3C,0xD4,0x56
             .db   0x6B,0x7A,0x59,0x97,0x29,0x21,0xAF,0xC5,0xB6,0x5A,0x99,0x8E,0x71,0x54,0xED,0xCD


;Skein-256:   256-bit hash, msgLen =   192 bits, data = 'random'

             .dw   TestSkeinTabResult33-TestSkeinTabMessagedata33
TestSkeinTabMessagedata33:
             .db   0xFB,0xD1,0x7C,0x26,0xB6,0x1A,0x82,0xE1,0x2E,0x12,0x5F,0x0D,0x45,0x9B,0x96,0xC9
             .db   0x1A,0xB4,0x83,0x7D,0xFF,0x22,0xB3,0x9B
TestSkeinTabResult33:
             .db   0xB4,0xAB,0xEB,0x4C,0xB4,0x8B,0xDD,0x25,0x65,0xA6,0x5B,0x2E,0x61,0x14,0xBA,0xED
             .db   0x24,0xCF,0x05,0xB8,0x24,0x2A,0xB0,0x91,0x0E,0x1F,0xFE,0x0B,0xEC,0xF0,0x3D,0xC6


;Skein-256:   256-bit hash, msgLen =   256 bits, data = 'random'

             .dw   TestSkeinTabResult34-TestSkeinTabMessagedata34
TestSkeinTabMessagedata34:
             .db   0xFB,0xD1,0x7C,0x26,0xB6,0x1A,0x82,0xE1,0x2E,0x12,0x5F,0x0D,0x45,0x9B,0x96,0xC9
             .db   0x1A,0xB4,0x83,0x7D,0xFF,0x22,0xB3,0x9B,0x78,0x43,0x94,0x30,0xCD,0xFC,0x5D,0xC8
TestSkeinTabResult34:
             .db   0xFC,0xAE,0xCD,0x67,0x37,0xC0,0x5C,0x29,0x06,0x9D,0x6F,0x69,0x98,0x63,0x97,0xC9
             .db   0x3D,0x0D,0x94,0x82,0x58,0x27,0x7C,0xD0,0x47,0x24,0x27,0x2B,0x7C,0xA9,0x71,0x34


;Skein-256:   256-bit hash, msgLen =   384 bits, data = 'random'

             .dw   TestSkeinTabResult35-TestSkeinTabMessagedata35
TestSkeinTabMessagedata35:
             .db   0xFB,0xD1,0x7C,0x26,0xB6,0x1A,0x82,0xE1,0x2E,0x12,0x5F,0x0D,0x45,0x9B,0x96,0xC9
             .db   0x1A,0xB4,0x83,0x7D,0xFF,0x22,0xB3,0x9B,0x78,0x43,0x94,0x30,0xCD,0xFC,0x5D,0xC8
             .db   0x78,0xBB,0x39,0x3A,0x1A,0x5F,0x79,0xBE,0xF3,0x09,0x95,0xA8,0x5A,0x12,0x92,0x33
TestSkeinTabResult35:
             .db   0x88,0x33,0x39,0xA8,0x11,0x28,0x64,0xF6,0x8F,0x16,0xF7,0x35,0x64,0x52,0x0F,0x97
             .db   0xDD,0xBB,0x97,0xDB,0x56,0x8D,0x82,0x34,0xF3,0xBC,0x58,0x53,0x01,0x89,0x4D,0xA5


;Skein-256:   256-bit hash, msgLen =   512 bits, data = 'random'

             .dw   TestSkeinTabResult36-TestSkeinTabMessagedata36
TestSkeinTabMessagedata36:
             .db   0xFB,0xD1,0x7C,0x26,0xB6,0x1A,0x82,0xE1,0x2E,0x12,0x5F,0x0D,0x45,0x9B,0x96,0xC9
             .db   0x1A,0xB4,0x83,0x7D,0xFF,0x22,0xB3,0x9B,0x78,0x43,0x94,0x30,0xCD,0xFC,0x5D,0xC8
             .db   0x78,0xBB,0x39,0x3A,0x1A,0x5F,0x79,0xBE,0xF3,0x09,0x95,0xA8,0x5A,0x12,0x92,0x33
             .db   0x39,0xBA,0x8A,0xB7,0xD8,0xFC,0x6D,0xC5,0xFE,0xC6,0xF4,0xED,0x22,0xC1,0x22,0xBB
TestSkeinTabResult36:
             .db   0xB7,0xAC,0x80,0xEB,0xB7,0xA3,0x67,0x17,0xC7,0x19,0xC2,0xA2,0xF3,0x08,0xC8,0x8A
             .db   0x32,0x66,0xFC,0xFB,0x88,0x93,0xC4,0x96,0x15,0xAC,0x98,0xBD,0xD5,0x92,0xF0,0xEC


;Skein-256:   256-bit hash, msgLen =   768 bits, data = 'random'

             .dw   TestSkeinTabResult37-TestSkeinTabMessagedata37
TestSkeinTabMessagedata37:
             .db   0xFB,0xD1,0x7C,0x26,0xB6,0x1A,0x82,0xE1,0x2E,0x12,0x5F,0x0D,0x45,0x9B,0x96,0xC9
             .db   0x1A,0xB4,0x83,0x7D,0xFF,0x22,0xB3,0x9B,0x78,0x43,0x94,0x30,0xCD,0xFC,0x5D,0xC8
             .db   0x78,0xBB,0x39,0x3A,0x1A,0x5F,0x79,0xBE,0xF3,0x09,0x95,0xA8,0x5A,0x12,0x92,0x33
             .db   0x39,0xBA,0x8A,0xB7,0xD8,0xFC,0x6D,0xC5,0xFE,0xC6,0xF4,0xED,0x22,0xC1,0x22,0xBB
             .db   0xE7,0xEB,0x61,0x98,0x18,0x92,0x96,0x6D,0xE5,0xCE,0xF5,0x76,0xF7,0x1F,0xC7,0xA8
             .db   0x0D,0x14,0xDA,0xB2,0xD0,0xC0,0x39,0x40,0xB9,0x5B,0x9F,0xB3,0xA7,0x27,0xC6,0x6A
TestSkeinTabResult37:
             .db   0xA9,0x8C,0xFE,0x1F,0xC4,0x71,0xF0,0xE7,0xBA,0x28,0x08,0x46,0x67,0x38,0xDF,0x24
             .db   0x8C,0xB1,0x9E,0x62,0x15,0xBF,0xD3,0x06,0x50,0xFC,0x29,0xEF,0x40,0xFA,0x32,0x1D


;Skein-256:   256-bit hash, msgLen =  1024 bits, data = 'random'

             .dw   TestSkeinTabResult38-TestSkeinTabMessagedata38
TestSkeinTabMessagedata38:
             .db   0xFB,0xD1,0x7C,0x26,0xB6,0x1A,0x82,0xE1,0x2E,0x12,0x5F,0x0D,0x45,0x9B,0x96,0xC9
             .db   0x1A,0xB4,0x83,0x7D,0xFF,0x22,0xB3,0x9B,0x78,0x43,0x94,0x30,0xCD,0xFC,0x5D,0xC8
             .db   0x78,0xBB,0x39,0x3A,0x1A,0x5F,0x79,0xBE,0xF3,0x09,0x95,0xA8,0x5A,0x12,0x92,0x33
             .db   0x39,0xBA,0x8A,0xB7,0xD8,0xFC,0x6D,0xC5,0xFE,0xC6,0xF4,0xED,0x22,0xC1,0x22,0xBB
             .db   0xE7,0xEB,0x61,0x98,0x18,0x92,0x96,0x6D,0xE5,0xCE,0xF5,0x76,0xF7,0x1F,0xC7,0xA8
             .db   0x0D,0x14,0xDA,0xB2,0xD0,0xC0,0x39,0x40,0xB9,0x5B,0x9F,0xB3,0xA7,0x27,0xC6,0x6A
             .db   0x6E,0x1F,0xF0,0xDC,0x31,0x1B,0x9A,0xA2,0x1A,0x30,0x54,0x48,0x48,0x02,0x15,0x4C
             .db   0x18,0x26,0xC2,0xA2,0x7A,0x09,0x14,0x15,0x2A,0xEB,0x76,0xF1,0x16,0x8D,0x44,0x10
TestSkeinTabResult38:
             .db   0x23,0xEE,0x3D,0xAA,0xF7,0x6F,0x75,0xDA,0xFD,0xE5,0xEB,0x7C,0x80,0x1F,0x3F,0x77
             .db   0x23,0x27,0x29,0x0D,0xBE,0x18,0x46,0xE9,0x78,0xAD,0xAC,0x97,0xF5,0xFA,0x2B,0x6D


;Skein-256:   256-bit hash, msgLen =  2048 bits, data = 'random'

             .dw   TestSkeinTabResult39-TestSkeinTabMessagedata39
TestSkeinTabMessagedata39:
             .db   0xFB,0xD1,0x7C,0x26,0xB6,0x1A,0x82,0xE1,0x2E,0x12,0x5F,0x0D,0x45,0x9B,0x96,0xC9
             .db   0x1A,0xB4,0x83,0x7D,0xFF,0x22,0xB3,0x9B,0x78,0x43,0x94,0x30,0xCD,0xFC,0x5D,0xC8
             .db   0x78,0xBB,0x39,0x3A,0x1A,0x5F,0x79,0xBE,0xF3,0x09,0x95,0xA8,0x5A,0x12,0x92,0x33
             .db   0x39,0xBA,0x8A,0xB7,0xD8,0xFC,0x6D,0xC5,0xFE,0xC6,0xF4,0xED,0x22,0xC1,0x22,0xBB
             .db   0xE7,0xEB,0x61,0x98,0x18,0x92,0x96,0x6D,0xE5,0xCE,0xF5,0x76,0xF7,0x1F,0xC7,0xA8
             .db   0x0D,0x14,0xDA,0xB2,0xD0,0xC0,0x39,0x40,0xB9,0x5B,0x9F,0xB3,0xA7,0x27,0xC6,0x6A
             .db   0x6E,0x1F,0xF0,0xDC,0x31,0x1B,0x9A,0xA2,0x1A,0x30,0x54,0x48,0x48,0x02,0x15,0x4C
             .db   0x18,0x26,0xC2,0xA2,0x7A,0x09,0x14,0x15,0x2A,0xEB,0x76,0xF1,0x16,0x8D,0x44,0x10
             .db   0xE1,0x14,0xAA,0x47,0xF7,0xC5,0xC6,0x15,0x43,0xC4,0xD9,0x59,0x18,0x82,0x34,0xF7
             .db   0x97,0xF4,0x5A,0x1D,0x16,0x65,0xE3,0x76,0x46,0xD8,0x12,0x9A,0x45,0xEE,0x70,0x78
             .db   0x09,0x91,0xBB,0x6B,0x10,0x02,0x39,0xE4,0x66,0xD5,0x8D,0x4C,0xDD,0x9D,0x9D,0x01
             .db   0x90,0xAB,0x64,0x47,0x0D,0xDC,0x87,0xF5,0xE5,0x09,0xE9,0xA8,0xCF,0x82,0x4F,0x58
             .db   0xEF,0x04,0x73,0x2E,0xAB,0x28,0x09,0x2D,0x18,0xA5,0xAD,0xA4,0x5B,0x6D,0x49,0xFB
             .db   0x0F,0x33,0xF4,0xCC,0x07,0xE3,0x9E,0xC6,0x44,0x9E,0x8C,0x0A,0xBB,0x17,0xC6,0x58
             .db   0x66,0x00,0x9A,0x3D,0x9C,0x31,0xC0,0xD7,0x65,0xE4,0xAF,0x88,0xB8,0x60,0x23,0xE9
             .db   0xA0,0x67,0xE3,0x32,0x0C,0x09,0x24,0x6A,0x3F,0xAE,0x8A,0x3F,0xD9,0x7C,0x48,0x7E
TestSkeinTabResult39:
             .db   0xA8,0x5E,0xE5,0x3D,0x6D,0x7B,0xA5,0x2E,0x6E,0xE8,0x42,0x24,0x93,0x13,0x7F,0xF3
             .db   0xE7,0x78,0x13,0xBF,0xBF,0xF1,0xFB,0xA5,0x9D,0xEC,0x42,0x50,0x42,0x7D,0x82,0x34

TestSkeinTabEnd:




TestThreeFishTab:

;-------
;tweak
            .db   0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F  ;tweak
;key
            .db   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F  ;key
            .db   0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F
;plaintext
            .db   0xFF,0xFE,0xFD,0xFC,0xFB,0xFA,0xF9,0xF8,0xF7,0xF6,0xF5,0xF4,0xF3,0xF2,0xF1,0xF0  ;plaintext
            .db   0xEF,0xEE,0xED,0xEC,0xEB,0xEA,0xE9,0xE8,0xE7,0xE6,0xE5,0xE4,0xE3,0xE2,0xE1,0xE0
;ciphertext
            .db   0x1E,0x9B,0x8F,0x64,0x1B,0xED,0x95,0x11,0xBE,0x4F,0x40,0xDF,0x57,0xC3,0xD7,0xA1
            .db   0xBC,0x42,0x71,0x8E,0xDD,0x7A,0xF7,0x13,0x9B,0x3D,0x4C,0x52,0xB2,0xA9,0x20,0xF8
             
;-----
;tweak
            .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
;key
            .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
            .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
;plaintext
            .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
            .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
;ciphertext
            .db   0xE3,0x97,0x56,0xF9,0xF3,0xB6,0xCF,0x3F,0xF9,0x1D,0x2B,0xC3,0xD3,0x24,0xCE,0x61
            .db   0x85,0x74,0xEA,0x16,0x23,0xB2,0x36,0x7F,0x88,0x38,0x2E,0x2A,0x93,0xAF,0xA8,0x58
             



;test vectors created from the outputs of configuration UBI,
;  given in appendix B of the Skein paper
;
;the following is the "plain" 256-128 Skein configuration UBI
;tweak
            .db   0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC4
;key
            .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
            .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
;plaintext
            .db   'S','H','A','3'               ;schema identifier
            .db                       0x01,0x00 ;version
            .db                                 0x00,0x00 ;reserved
            .db                                           0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00  ;output length
            .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ;reserve
;ciphertext
            .db   0xB2,0xAA,0x3E,0x0E,0xA3,0x7E,0x2F,0x30,0xAB,0x75,0x13,0x69,0x3A,0x68,0xE4,0xAD
            .db   0x0A,0xAB,0x08,0xF2,0xBE,0xFA,0x5C,0x97,0x5B,0xF5,0x31,0xF8,0x95,0xBA,0xF4,0x2A
; after xor with plaintext. i.e. the UBI output = constant input to rest of "plain" SKEIN-256-128 hash
;            .db   0E1h,0E2h,07Fh,03Dh,0A2h,07Eh,02Fh,030h,02Bh,075h,013h,069h,03Ah,068h,0E4h,0ADh
;            .db   00Ah,0ABh,008h,0F2h,0BEh,0FAh,05Ch,097h,05Bh,0F5h,031h,0F8h,095h,0BAh,0F4h,02Ah



             
;the following is the "plain" 256-160 Skein configuration UBI
;tweak
            .db   0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC4
;key
            .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
            .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
;plaintext
            .db   'S','H','A','3'               ;schema identifier
            .db                       0x01,0x00 ;version
            .db                                 0x00,0x00 ;reserved
            .db                                           0xA0,0x00,0x00,0x00,0x00,0x00,0x00,0x00  ;output length
            .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ;reserve
;ciphertext
            .db   0x70,0x3F,0x29,0x90,0x81,0x0D,0x8A,0xA3,0x69,0xFF,0x63,0x59,0x6A,0xDB,0x3C,0xB7
            .db   0x47,0xB4,0xA1,0x07,0xEA,0xE8,0x33,0x96,0x22,0x9C,0x52,0xC9,0x9E,0xD0,0x0E,0xCA
; after xor with plaintext. i.e. the UBI output = constant input to rest of "plain" SKEIN-256-160 hash
;            .db   023h,077h,068h,0A3h,080h,00Dh,08Ah,0A3h,0C9h,0FFh,063h,059h,06Ah,0DBh,03Ch,0B7h
;            .db   047h,0B4h,0A1h,007h,0EAh,0E8h,033h,096h,022h,09Ch,052h,0C9h,09Eh,0D0h,00Eh,0CAh


             
;the following is the "plain" 256-224 Skein configuration UBI
;tweak
            .db   0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC4
;key
            .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
            .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
;plaintext
            .db   'S','H','A','3'               ;schema identifier
            .db                       0x01,0x00 ;version
            .db                                 0x00,0x00 ;reserved
            .db                                           0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00  ;output length
            .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ;reserve
;ciphertext
            .db   0x62,0xBC,0xA1,0xA9,0x68,0x29,0x09,0xB8,0x3C,0x29,0x69,0xA0,0x14,0xDC,0x40,0xD3
            .db   0x5A,0xDC,0xE4,0xBD,0x94,0x65,0x86,0xAE,0x1D,0xEA,0x60,0x5A,0xC2,0x67,0x97,0x33
; after xor with plaintext. i.e. the UBI output = constant input to rest of "plain" SKEIN-256-224 hash
;            .db   031h,0F4h,0E0h,09Ah,069h,029h,009h,0B8h,0DCh,029h,069h,0A0h,014h,0DCh,040h,0D3h
;            .db   05Ah,0DCh,0E4h,0BDh,094h,065h,086h,0AEh,01Dh,0EAh,060h,05Ah,0C2h,067h,097h,033h



;the following is the "plain" 256-256 Skein configuration UBI
;tweak
            .db   0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC4
;key
            .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
            .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
;plaintext
            .db   'S','H','A','3'               ;schema identifier
            .db                       0x01,0x00 ;version
            .db                                 0x00,0x00 ;reserved
            .db                                           0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00  ;output length
            .db   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ;reserve
;ciphertext
            .db   0x15,0x48,0x27,0x3D,0x69,0x12,0x85,0x38,0x01,0xFE,0xA8,0xC5,0xDE,0xD5,0x72,0x4B
            .db   0xA5,0xB3,0x5E,0xCA,0x98,0x92,0x1A,0x28,0xC4,0x70,0x60,0xF4,0x49,0x52,0xCA,0x54
; after xor with plaintext. i.e. the UBI output = constant input to rest of "plain" SKEIN-256-256 hash
;            .db   046h,000h,066h,00Eh,068h,012h,085h,038h,001h,0FFh,0A8h,0C5h,0DEh,0D5h,072h,04Bh
;            .db   0A5h,0B3h,05Eh,0CAh,098h,092h,01Ah,028h,0C4h,070h,060h,0F4h,049h,052h,0CAh,054h
TestThreeFishTabEnd:


      

;------------------------------------------------- Skein-256-256 ----------------------------------------------------------

;input pointer in Z, data size in bytes in Y
;returns hash in registers
;
;in this example, we will read input data from code memory; it is trivial to modify it to read from data memory.
;
;we will perform Skein-256-256 as an example here; it is easy to modify it for any other output size below 256, 
;  simply replace the input chain value, and throw away the unneeded bits from the output

.dseg

SkeinBackupYL:   .byte   1 ;order important
SkeinBackupYH:   .byte   1
SkeinBackupZL:   .byte   1
SkeinBackupZH:   .byte   1
SkeinBackupR1:   .byte   1

.cseg

Skein:
         sts   SkeinBackupZL,ZL
         sts   SkeinBackupZH,ZH
         sts   SkeinBackupYL,YL
         sts   SkeinBackupYH,YH

         ldi   ZL,LOW(Skein256256InitTab*2)
         ldi   ZH,HIGH(Skein256256InitTab*2)
         ldi   YL,LOW(Key)
         ldi   YH,HIGH(Key)
SkeinX01:
         lpm
         adiw  ZL,1
         st    Y+,r0
         cpi   YL,LOW(Key + WORDSIZE*DATASIZE)
         brne  SkeinX01

         ldi   YL,LOW(Tweak)
         ldi   YH,HIGH(Tweak)
         clr   r0
SkeinX02:
         st    Y+,r0
         cpi   YL,LOW(Tweak + 8 + 7)
         brne  SkeinX02

         ldi   r27, 48+0x40 ;Type=Message, set First flag
         sts   Tweak+15, r27

SkeinLoop:
         ldi   r27, 0x20
         mov   r1,r27
         clr   r0
         lds   YL,SkeinBackupYL
         lds   YH,SkeinBackupYH
         cpi   YL,0x20+1
         cpc   YH,r0
         brcc  SkeinX11
         mov   r1,YL
         lds   r27,Tweak+15
         ori   r27,0x80           ;set Final flag
         sts   Tweak+15,r27
SkeinX11:
         sts   SkeinBackupR1,r1
         sub   YL,r1
         sbc   YH,r0
         sts   SkeinBackupYL,YL
         sts   SkeinBackupYH,YH
         lds   YL,Tweak+0
         lds   YH,Tweak+1
         add   YL,r1
         adc   YH,r0
         sts   Tweak+0,YL
         sts   Tweak+1,YH

         lds   ZL,SkeinBackupZL
         lds   ZH,SkeinBackupZH
         mov   YL,r0           
         mov   YH,r0          
         sts   Temp+0,r0    ;prepare as "content" of r0/r1
         sts   Temp+1,r0
         sts   Temp+2,r0    ;prepare as "content" of ZL/ZH
         sts   Temp+3,r0
         or    r1,r1                  ;test for the pathologic zero input size
         breq  SkeinX20
         lpm
         adiw  ZL,1
         adiw  YL,1
         sts   Temp+0,r0
         dec   r1
         breq  SkeinX20
         lpm
         adiw  ZL,1
         adiw  YL,1
         sts   Temp+1,r0
SkeinX12:
         dec   r1
         breq  SkeinX20
         lpm
         adiw  ZL,1
         st    Y+,r0
         cpi   YL,28   ;LOW(YL)
         brne  SkeinX12
         dec   r1
         breq  SkeinX22
         lpm
         adiw  ZL,1
         mov   YL,r0
         dec   r1
         breq  SkeinX23
         lpm
         adiw  ZL,1
         mov   YH,r0
         dec   r1
         breq  SkeinX24
         lpm
         adiw  ZL,1
         sts   Temp+2,r0
         dec   r1
         breq  SkeinX24
         lpm
         adiw  ZL,1
         sts   Temp+3,r0
         rjmp  SkeinX24
SkeinX20:
         clr   r0
SkeinX21:
         st    Y+,r0
         cpi   YL,28
         brne  SkeinX21
SkeinX22:
         clr   YL
SkeinX23:
         clr   YH
SkeinX24:
         lds   r0,Temp+0
         lds   r1,Temp+1
         lds   ZL,Temp+2
         lds   ZH,Temp+3

         rcall ThreeFish
         

         sts   Key+0,r0
         sts   Key+1,r1
         sts   Key+28,YL
         sts   Key+29,YH
         sts   Key+30,ZL
         sts   Key+31,ZH
         ldi   YL,2
         clr   YH      ;ldi   YH,0
         ldi   ZL,LOW(Key+2)
         ldi   ZH,HIGH(Key+2)
SkeinX31:
         ld    r0,Y+
         st    Z+,r0
         cpi   YL,28
         brne  SkeinX31
         
         lds   ZL,SkeinBackupZL
         lds   ZH,SkeinBackupZH
         lds   r1,SkeinBackupR1
         ldi   YL,LOW(Key)
         ldi   YH,HIGH(Key)
         or    r1,r1
         breq  SkeinX40
SkeinX32:
         lpm
         adiw  ZL,1
         ld    r2,Y
         eor   r2,r0
         st    Y+,r2
         dec   r1
         brne  SkeinX32
SkeinX40:
         sts   SkeinBackupZL,ZL
         sts   SkeinBackupZH,ZH
         lds   r27,Tweak+15
         andi  r27,0xBF
         sts   Tweak+15,r27
         sbrs  r27,7
         rjmp  SkeinLoop

         ldi   r27,8
         sts   Tweak+0,r27
         clr   r27
         sts   Tweak+1,r27
         ldi   r27,63+0x40+0x80   ;type=Output, first & finish
         sts   Tweak+15,r27

         clr   r0
         clr   ZH
         ldi   ZL,30
SkeinX41:
         st    -Z,r0
         cpi   ZL,0
         brne  SkeinX41

         rcall ThreeFish

         ret


      

Skein256256InitTab:
            .db   0x46,0x00,0x66,0x0E,0x68,0x12,0x85,0x38,0x01,0xFF,0xA8,0xC5,0xDE,0xD5,0x72,0x4B
            .db   0xA5,0xB3,0x5E,0xCA,0x98,0x92,0x1A,0x28,0xC4,0x70,0x60,0xF4,0x49,0x52,0xCA,0x54


;---------------------------------------------------- ThreeFish-256 ----------------------------------------------------------------------------
;input in Tweak, Key and all the registers as data
;output in the registers



.equ WORDSIZE = 8
.equ DATASIZE = 4
.equ ROUNDS   = 72


.dseg
;X is placed in r0-r31
Key:        .byte   WORDSIZE*(DATASIZE + 1)
Tweak:      .byte   WORDSIZE*(2+1)

Temp:       .byte   8 + 1

;RoundCnt:   .byte   1  
;KeyPtr:     .byte   1
;TweakPtr:   .byte   1
;we're gonna spare
.equ    RoundCnt = Temp+1
.equ    KeyPtr   = Temp+2
.equ    TweakPtr = Temp+3


.cseg

ThreeFish:


.def  X0_0  =  r00
.def  X0_1  =  r01
.def  X0_2  =  r02
.def  X0_3  =  r03
.def  X0_4  =  r04
.def  X0_5  =  r05
.def  X0_6  =  r06
.def  X0_7  =  r07
.def  X1_0  =  r08
.def  X1_1  =  r09
.def  X1_2  =  r10
.def  X1_3  =  r11
.def  X1_4  =  r12
.def  X1_5  =  r13
.def  X1_6  =  r14
.def  X1_7  =  r15
.def  X2_0  =  r16
.def  X2_1  =  r17
.def  X2_2  =  r18
.def  X2_3  =  r19
.def  X2_4  =  r20
.def  X2_5  =  r21
.def  X2_6  =  r22
.def  X2_7  =  r23
.def  X3_0  =  r24
.def  X3_1  =  r25
.def  X3_2  =  r26
.def  X3_3  =  r27
.def  X3_4  =  r28
.def  X3_5  =  r29
.def  X3_6  =  r30
.def  X3_7  =  r31



.def  TempKey0 = r24  ;X3_0
.def  TempKey1 = r25  ;X3_1
.def  TempKey2 = r26  ;X3_2
.def  TempKey3 = r27  ;X3_3
.def  TempKey4 = r28  ;X3_4 
.def  TempKey5 = r29  ;X3_5
.def  TempKey6 = r30  ;X3_6
.def  TempKey7 = r31  ;X3_7
.def  TempReg  = r23  ;X2_7


;initial key and tweak setup, simultaneously initial key injection
      sts  Temp+0, TempKey0        ;first, we have to swap out 8 + 1 bytes to Temp, to make space for Key "checksum" calculation
      sts  Temp+1, TempKey1
      sts  Temp+2, TempKey2
      sts  Temp+3, TempKey3
      sts  Temp+4, TempKey4
      sts  Temp+5, TempKey5
      sts  Temp+6, TempKey6
      sts  Temp+7, TempKey7


      ;first, add tweak, simultaneously with creating the tweak xor
      lds   TempKey0, Tweak + 1*WORDSIZE + 0
      add   X2_0, TempKey0
      lds   TempKey1, Tweak + 1*WORDSIZE + 1
      adc   X2_1, TempKey1
      lds   TempKey2, Tweak + 1*WORDSIZE + 2
      adc   X2_2, TempKey2
      lds   TempKey3, Tweak + 1*WORDSIZE + 3
      adc   X2_3, TempKey3
      lds   TempKey4, Tweak + 1*WORDSIZE + 4
      adc   X2_4, TempKey4
      lds   TempKey5, Tweak + 1*WORDSIZE + 5
      adc   X2_5, TempKey5
      lds   TempKey6, Tweak + 1*WORDSIZE + 6
      adc   X2_6, TempKey6
      lds   TempKey7, Tweak + 1*WORDSIZE + 7
      adc   X2_7, TempKey7
          
      sts   Temp+8, TempReg

      lds   TempReg, Tweak + 0*WORDSIZE + 0
      add   X1_0, TempReg
      eor   TempReg, TempKey0
      sts   Tweak + 2*WORDSIZE + 0, TempReg
      lds   TempReg, Tweak + 0*WORDSIZE + 1
      adc   X1_1, TempReg
      eor   TempReg, TempKey1
      sts   Tweak + 2*WORDSIZE + 1, TempReg
      lds   TempReg, Tweak + 0*WORDSIZE + 2
      adc   X1_2, TempReg
      eor   TempReg, TempKey2
      sts   Tweak + 2*WORDSIZE + 2, TempReg
      lds   TempReg, Tweak + 0*WORDSIZE + 3
      adc   X1_3, TempReg
      eor   TempReg, TempKey3
      sts   Tweak + 2*WORDSIZE + 3, TempReg
      lds   TempReg, Tweak + 0*WORDSIZE + 4
      adc   X1_4, TempReg
      eor   TempReg, TempKey4
      sts   Tweak + 2*WORDSIZE + 4, TempReg
      lds   TempReg, Tweak + 0*WORDSIZE + 5
      adc   X1_5, TempReg
      eor   TempReg, TempKey5
      sts   Tweak + 2*WORDSIZE + 5, TempReg
      lds   TempReg, Tweak + 0*WORDSIZE + 6
      adc   X1_6, TempReg
      eor   TempReg, TempKey6
      sts   Tweak + 2*WORDSIZE + 6, TempReg
      lds   TempReg, Tweak + 0*WORDSIZE + 7
      adc   X1_7, TempReg
      eor   TempReg, TempKey7
      sts   Tweak + 2*WORDSIZE + 7, TempReg


      lds  TempKey0, Key + 0*WORDSIZE + 0  ;now get key and add
      add  X0_0, TempKey0
      lds  TempKey1, Key + 0*WORDSIZE + 1
      adc  X0_1, TempKey1
      lds  TempKey2, Key + 0*WORDSIZE + 2
      adc  X0_2, TempKey2
      lds  TempKey3, Key + 0*WORDSIZE + 3
      adc  X0_3, TempKey3
      lds  TempKey4, Key + 0*WORDSIZE + 4
      adc  X0_4, TempKey4
      lds  TempKey5, Key + 0*WORDSIZE + 5
      adc  X0_5, TempKey5
      lds  TempKey6, Key + 0*WORDSIZE + 6
      adc  X0_6, TempKey6
      lds  TempKey7, Key + 0*WORDSIZE + 7
      adc  X0_7, TempKey7

      ldi  TempReg, 0x55
      eor  TempKey0, TempReg
      eor  TempKey1, TempReg
      eor  TempKey2, TempReg
      eor  TempKey3, TempReg
      eor  TempKey4, TempReg
      eor  TempKey5, TempReg
      eor  TempKey6, TempReg
      eor  TempKey7, TempReg

      lds  TempReg, Key + 1*WORDSIZE + 0
      add  X1_0, TempReg
      eor  TempKey0, TempReg
      lds  TempReg, Key + 1*WORDSIZE + 1
      adc  X1_1, TempReg
      eor  TempKey1, TempReg
      lds  TempReg, Key + 1*WORDSIZE + 2
      adc  X1_2, TempReg
      eor  TempKey2, TempReg
      lds  TempReg, Key + 1*WORDSIZE + 3
      adc  X1_3, TempReg
      eor  TempKey3, TempReg
      lds  TempReg, Key + 1*WORDSIZE + 4
      adc  X1_4, TempReg
      eor  TempKey4, TempReg
      lds  TempReg, Key + 1*WORDSIZE + 5
      adc  X1_5, TempReg
      eor  TempKey5, TempReg
      lds  TempReg, Key + 1*WORDSIZE + 6
      adc  X1_6, TempReg
      eor  TempKey6, TempReg
      lds  TempReg, Key + 1*WORDSIZE + 7
      adc  X1_7, TempReg
      eor  TempKey7, TempReg

      lds  TempReg, Key + 2*WORDSIZE + 0
      add  X2_0, TempReg
      eor  TempKey0, TempReg
      lds  TempReg, Key + 2*WORDSIZE + 1
      adc  X2_1, TempReg
      eor  TempKey1, TempReg
      lds  TempReg, Key + 2*WORDSIZE + 2
      adc  X2_2, TempReg
      eor  TempKey2, TempReg
      lds  TempReg, Key + 2*WORDSIZE + 3
      adc  X2_3, TempReg
      eor  TempKey3, TempReg
      lds  TempReg, Key + 2*WORDSIZE + 4
      adc  X2_4, TempReg
      eor  TempKey4, TempReg
      lds  TempReg, Key + 2*WORDSIZE + 5
      adc  X2_5, TempReg
      eor  TempKey5, TempReg
      lds  TempReg, Key + 2*WORDSIZE + 6
      adc  X2_6, TempReg
      eor  TempKey6, TempReg

      lds  TempReg, Temp+8
.def  TempReg  =  r16  ;X2_0
      sts  Temp+8, TempReg 

      lds  TempReg, Key + 2*WORDSIZE + 7
      adc  X2_7, TempReg
      eor  TempKey7, TempReg

      lds  TempReg, Key + 3*WORDSIZE + 0
      eor  TempKey0, TempReg
      sts  Key+DATASIZE*WORDSIZE + 0, TempKey0
      lds  TempKey0, Temp+0
      add  X3_0, TempReg
      lds  TempReg, Key + 3*WORDSIZE + 1
      eor  TempKey1, TempReg
      sts  Key+DATASIZE*WORDSIZE + 1, TempKey1
      lds  TempKey1, Temp+1
      adc  X3_1, TempReg
      lds  TempReg, Key + 3*WORDSIZE + 2
      eor  TempKey2, TempReg
      sts  Key+DATASIZE*WORDSIZE + 2, TempKey2
      lds  TempKey2, Temp+2
      adc  X3_2, TempReg
      lds  TempReg, Key + 3*WORDSIZE + 3
      eor  TempKey3, TempReg
      sts  Key+DATASIZE*WORDSIZE + 3, TempKey3
      lds  TempKey3, Temp+3
      adc  X3_3, TempReg
      lds  TempReg, Key + 3*WORDSIZE + 4
      eor  TempKey4, TempReg
      sts  Key+DATASIZE*WORDSIZE + 4, TempKey4 
      lds  TempKey4, Temp+4
      adc  X3_4, TempReg
      lds  TempReg, Key + 3*WORDSIZE + 5
      eor  TempKey5, TempReg
      sts  Key+DATASIZE*WORDSIZE + 5, TempKey5
      lds  TempKey5, Temp+5
      adc  X3_5, TempReg
      lds  TempReg, Key + 3*WORDSIZE + 6
      eor  TempKey6, TempReg
      sts  Key+DATASIZE*WORDSIZE + 6, TempKey6
      lds  TempKey6, Temp+6
      adc  X3_6, TempReg
      lds  TempReg, Key + 3*WORDSIZE + 7
      eor  TempKey7, TempReg
      sts  Key+DATASIZE*WORDSIZE + 7, TempKey7
      lds  TempKey7, Temp+7
      adc  X3_7, TempReg

      clr  TempReg
      sts  RoundCnt, TempReg
      inc  TempReg
      sts  KeyPtr, TempReg
      sts  TweakPtr, TempReg

      lds  TempReg, Temp+8

ThreeFishLoop:
;let's define some macros first
      .macro add_0_1
      add  X0_0, X1_0
      adc  X0_1, X1_1
      adc  X0_2, X1_2
      adc  X0_3, X1_3
      adc  X0_4, X1_4
      adc  X0_5, X1_5
      adc  X0_6, X1_6
      adc  X0_7, X1_7
      .endmacro
      .macro rota_right_1
      clc
      sbrc X1_0,0
      sec                   ;sbrc won't leak, as sec is 1-word 1-cyc, so sbrc would take the same time in both cases
      ror  X1_7
      ror  X1_6
      ror  X1_5
      ror  X1_4
      ror  X1_3
      ror  X1_2
      ror  X1_1
      ror  X1_0
      .endmacro
      .macro rota_left_1
      clc
      sbrc X1_7,7
      sec                   
      rol  X1_0
      rol  X1_1
      rol  X1_2
      rol  X1_3
      rol  X1_4
      rol  X1_5
      rol  X1_6
      rol  X1_7
      .endmacro
      .macro rota_right_3
      clc
      sbrc X3_0,0
      sec                   ;sbrc won't leak, as sec is 1-word 1-cyc, so sbrc would take the same time in both cases
      ror  X3_7
      ror  X3_6
      ror  X3_5
      ror  X3_4
      ror  X3_3
      ror  X3_2
      ror  X3_1
      ror  X3_0
      .endmacro
      .macro rota_left_3
      clc
      sbrc X3_7,7
      sec                   
      rol  X3_0
      rol  X3_1
      rol  X3_2
      rol  X3_3
      rol  X3_4
      rol  X3_5
      rol  X3_6
      rol  X3_7
      .endmacro
      .macro add_2_3
      add  X2_0, X3_0
      adc  X2_1, X3_1
      adc  X2_2, X3_2
      adc  X2_3, X3_3
      adc  X2_4, X3_4
      adc  X2_5, X3_5
      adc  X2_6, X3_6
      adc  X2_7, X3_7
      .endmacro

;--- d = 0
;           --- j = 0
      add_0_1
;rota 5: mod 8 = 5, div 8 = 0
;we use bit rr 3, rename - 1
      rota_right_1
      rota_right_1
      rota_right_1
      eor  X1_0, X0_1
      eor  X1_1, X0_2
      eor  X1_2, X0_3
      eor  X1_3, X0_4
      eor  X1_4, X0_5
      eor  X1_5, X0_6
      eor  X1_6, X0_7
      eor  X1_7, X0_0
;           --- j = 1
      add_2_3
;rota 56: mod 8 = 0, div 8 = 7
      eor  X3_0, X2_7
      eor  X3_1, X2_0
      eor  X3_2, X2_1
      eor  X3_3, X2_2
      eor  X3_4, X2_3
      eor  X3_5, X2_4
      eor  X3_6, X2_5
      eor  X3_7, X2_6

;--- d = 1

.def  X1_0  =  r25
.def  X1_1  =  r26
.def  X1_2  =  r27
.def  X1_3  =  r28
.def  X1_4  =  r29
.def  X1_5  =  r30
.def  X1_6  =  r31
.def  X1_7  =  r24

.def  X3_0  =  r15
.def  X3_1  =  r08
.def  X3_2  =  r09
.def  X3_3  =  r10
.def  X3_4  =  r11
.def  X3_5  =  r12
.def  X3_6  =  r13
.def  X3_7  =  r14
;           --- j = 0
      add_0_1
;rota 36: mod 8 = 4, div 8 = 4
      rota_left_1
      rota_left_1
      rota_left_1
      rota_left_1
      eor  X1_0, X0_4
      eor  X1_1, X0_5
      eor  X1_2, X0_6
      eor  X1_3, X0_7
      eor  X1_4, X0_0
      eor  X1_5, X0_1
      eor  X1_6, X0_2
      eor  X1_7, X0_3

;           --- j = 1
      add_2_3
;rota 28: mod 8 = 4, div 8 = 3
      rota_left_3
      rota_left_3
      rota_left_3
      rota_left_3
      eor  X3_0, X2_3 
      eor  X3_1, X2_4 
      eor  X3_2, X2_5 
      eor  X3_3, X2_6 
      eor  X3_4, X2_7
      eor  X3_5, X2_0
      eor  X3_6, X2_1
      eor  X3_7, X2_2


;--- d = 2
.def  X1_0  =  r12
.def  X1_1  =  r13
.def  X1_2  =  r14 
.def  X1_3  =  r15
.def  X1_4  =  r08
.def  X1_5  =  r09
.def  X1_6  =  r10
.def  X1_7  =  r11

.def  X3_0  =  r29
.def  X3_1  =  r30
.def  X3_2  =  r31
.def  X3_3  =  r24
.def  X3_4  =  r25
.def  X3_5  =  r26
.def  X3_6  =  r27
.def  X3_7  =  r28
;           --- j = 0
      add_0_1
;rota 13: mod 8 = 5, div 8 = 1
      rota_right_1
      rota_right_1
      rota_right_1
      eor  X1_0, X0_2
      eor  X1_1, X0_3
      eor  X1_2, X0_4
      eor  X1_3, X0_5
      eor  X1_4, X0_6
      eor  X1_5, X0_7
      eor  X1_6, X0_0
      eor  X1_7, X0_1

;           --- j = 1
      add_2_3
;rota 46: mod 8 = 6, div 8 = 5
      rota_right_3
      rota_right_3
      eor  X3_0, X2_6 
      eor  X3_1, X2_7 
      eor  X3_2, X2_0 
      eor  X3_3, X2_1 
      eor  X3_4, X2_2
      eor  X3_5, X2_3
      eor  X3_6, X2_4
      eor  X3_7, X2_5


;--- d = 3
.def  X1_0  =  r31
.def  X1_1  =  r24
.def  X1_2  =  r25 
.def  X1_3  =  r26
.def  X1_4  =  r27
.def  X1_5  =  r28
.def  X1_6  =  r29
.def  X1_7  =  r30

.def  X3_0  =  r10    
.def  X3_1  =  r11
.def  X3_2  =  r12
.def  X3_3  =  r13
.def  X3_4  =  r14
.def  X3_5  =  r15
.def  X3_6  =  r08
.def  X3_7  =  r09
;           --- j = 0
      add_0_1
;rota 58: mod 8 = 2, div 8 = 7
      rota_left_1
      rota_left_1
      eor  X1_0, X0_7
      eor  X1_1, X0_0
      eor  X1_2, X0_1
      eor  X1_3, X0_2
      eor  X1_4, X0_3
      eor  X1_5, X0_4
      eor  X1_6, X0_5
      eor  X1_7, X0_6

;           --- j = 1
      add_2_3
;rota 44: mod 8 = 4, div 8 = 5
      rota_left_3
      rota_left_3
      rota_left_3
      rota_left_3
      eor  X3_0, X2_5 
      eor  X3_1, X2_6 
      eor  X3_2, X2_7 
      eor  X3_3, X2_0 
      eor  X3_4, X2_1
      eor  X3_5, X2_2
      eor  X3_6, X2_3
      eor  X3_7, X2_4

;------------------------ key injection 

.def  X1_0  =  r13 
.def  X1_1  =  r14 
.def  X1_2  =  r15 
.def  X1_3  =  r08 
.def  X1_4  =  r09
.def  X1_5  =  r10
.def  X1_6  =  r11
.def  X1_7  =  r12

.def  X3_0  =  r24     
.def  X3_1  =  r25
.def  X3_2  =  r26
.def  X3_3  =  r27
.def  X3_4  =  r28
.def  X3_5  =  r29
.def  X3_6  =  r30
.def  X3_7  =  r31

;we unroll all 5 variants for key and all 3 for tweak
;this is fast but eats FLASH

;a couple of macros first
      .macro add_lower_key
      lds  TempReg,Key + @0*WORDSIZE + 0
      add  X0_0,TempReg
      lds  TempReg,Key + @0*WORDSIZE + 1
      adc  X0_1,TempReg
      lds  TempReg,Key + @0*WORDSIZE + 2
      adc  X0_2,TempReg
      lds  TempReg,Key + @0*WORDSIZE + 3
      adc  X0_3,TempReg
      lds  TempReg,Key + @0*WORDSIZE + 4
      adc  X0_4,TempReg
      lds  TempReg,Key + @0*WORDSIZE + 5
      adc  X0_5,TempReg
      lds  TempReg,Key + @0*WORDSIZE + 6
      adc  X0_6,TempReg
      lds  TempReg,Key + @0*WORDSIZE + 7
      adc  X0_7,TempReg

      lds  TempReg,Key + @1*WORDSIZE + 0
      add  X1_0,TempReg
      lds  TempReg,Key + @1*WORDSIZE + 1
      adc  X1_1,TempReg
      lds  TempReg,Key + @1*WORDSIZE + 2
      adc  X1_2,TempReg
      lds  TempReg,Key + @1*WORDSIZE + 3
      adc  X1_3,TempReg
      lds  TempReg,Key + @1*WORDSIZE + 4
      adc  X1_4,TempReg
      lds  TempReg,Key + @1*WORDSIZE + 5
      adc  X1_5,TempReg
      lds  TempReg,Key + @1*WORDSIZE + 6
      adc  X1_6,TempReg
      lds  TempReg,Key + @1*WORDSIZE + 7
      adc  X1_7,TempReg
      .endmacro

      .macro add_upper_key  
      lds  TempReg,Key + @0*WORDSIZE + 0
      add  X2_0,TempReg
      lds  TempReg,Key + @0*WORDSIZE + 1
      adc  X2_1,TempReg
      lds  TempReg,Key + @0*WORDSIZE + 2
      adc  X2_2,TempReg
      lds  TempReg,Key + @0*WORDSIZE + 3
      adc  X2_3,TempReg
      lds  TempReg,Key + @0*WORDSIZE + 4
      adc  X2_4,TempReg
      lds  TempReg,Key + @0*WORDSIZE + 5
      adc  X2_5,TempReg
      lds  TempReg,Key + @0*WORDSIZE + 6
      adc  X2_6,TempReg
      lds  TempReg,Key + @0*WORDSIZE + 7
      adc  X2_7,TempReg

      lds  TempReg,Key + @1*WORDSIZE + 0
      add  X3_0,TempReg
      lds  TempReg,Key + @1*WORDSIZE + 1
      adc  X3_1,TempReg
      lds  TempReg,Key + @1*WORDSIZE + 2
      adc  X3_2,TempReg
      lds  TempReg,Key + @1*WORDSIZE + 3
      adc  X3_3,TempReg
      lds  TempReg,Key + @1*WORDSIZE + 4
      adc  X3_4,TempReg
      lds  TempReg,Key + @1*WORDSIZE + 5
      adc  X3_5,TempReg
      lds  TempReg,Key + @1*WORDSIZE + 6
      adc  X3_6,TempReg
      lds  TempReg,Key + @1*WORDSIZE + 7
      adc  X3_7,TempReg
      .endmacro

      .macro add_tweak      
      lds  TempReg,Tweak + @0*WORDSIZE + 0
      add  X1_0,TempReg
      lds  TempReg,Tweak + @0*WORDSIZE + 1
      adc  X1_1,TempReg
      lds  TempReg,Tweak + @0*WORDSIZE + 2
      adc  X1_2,TempReg
      lds  TempReg,Tweak + @0*WORDSIZE + 3
      adc  X1_3,TempReg
      lds  TempReg,Tweak + @0*WORDSIZE + 4
      adc  X1_4,TempReg
      lds  TempReg,Tweak + @0*WORDSIZE + 5
      adc  X1_5,TempReg
      lds  TempReg,Tweak + @0*WORDSIZE + 6
      adc  X1_6,TempReg
      lds  TempReg,Tweak + @0*WORDSIZE + 7
      adc  X1_7,TempReg

      lds  TempReg,Tweak + @1*WORDSIZE + 0
      add  X2_0,TempReg
      lds  TempReg,Tweak + @1*WORDSIZE + 1
      adc  X2_1,TempReg
      lds  TempReg,Tweak + @1*WORDSIZE + 2
      adc  X2_2,TempReg
      lds  TempReg,Tweak + @1*WORDSIZE + 3
      adc  X2_3,TempReg
      lds  TempReg,Tweak + @1*WORDSIZE + 4
      adc  X2_4,TempReg
      lds  TempReg,Tweak + @1*WORDSIZE + 5
      adc  X2_5,TempReg
      lds  TempReg,Tweak + @1*WORDSIZE + 6
      adc  X2_6,TempReg
      lds  TempReg,Tweak + @1*WORDSIZE + 7
      adc  X2_7,TempReg
      .endmacro

.def  TempReg = r23 ;X2_7

      sts  Temp, TempReg
      lds  TempReg, KeyPtr
      sbrc TempReg,2
      rjmp TF_IK04
      sbrc TempReg,1
      rjmp TF_IKx2
      sbrc TempReg,0
      rjmp TF_IK01
;     rjmp TF_IK00
;intentional fallthrough
TF_IK00:
.def  TempReg = r23 ;X2_7
      inc  TempReg
      sts  KeyPtr,TempReg

      add_lower_key  0,1

      lds  TempReg,Temp
.def  TempReg = r00   ;X0_0
      sts  Temp, TempReg

      add_upper_key  2,3

      rjmp TF_ITx0

TF_IK01:
.def  TempReg = r23 ;X2_7
      inc  TempReg
      sts  KeyPtr,TempReg

      add_lower_key  1,2

      lds  TempReg,Temp
.def  TempReg = r00   ;X0_0
      sts  Temp, TempReg

      add_upper_key  3,4

      rjmp TF_ITx0

TF_IKx2:
.def  TempReg = r23 ;X2_7
      sbrc TempReg,0
      rjmp TF_IK03
;     rjmp TF_IK02
;intentional fallthrough
TF_IK02:
.def  TempReg = r23 ;X2_7
      inc  TempReg
      sts  KeyPtr,TempReg

      add_lower_key  2,3

      lds  TempReg,Temp
.def  TempReg = r00   ;X0_0
      sts  Temp, TempReg

      add_upper_key  4,0

      rjmp TF_ITx0

TF_IK03:
.def  TempReg = r23 ;X2_7
      inc  TempReg
      sts  KeyPtr,TempReg

      add_lower_key  3,4

      lds  TempReg,Temp
.def  TempReg = r00   ;X0_0
      sts  Temp, TempReg

      add_upper_key  0,1

      rjmp TF_ITx0


TF_IK04:
.def  TempReg = r23 ;X2_7
      clr  TempReg
      sts  KeyPtr,TempReg

      add_lower_key  4,0

      lds  TempReg,Temp
.def  TempReg = r00   ;X0_0
      sts  Temp, TempReg

      add_upper_key  1,2

;      rjmp TF_ITx0
      ;intentional fallthrough
TF_ITx0:
.def  TempReg = r00   ;X0_0
      lds  TempReg,TweakPtr
      sbrc TempReg,1
      rjmp TF_IT02
      sbrc TempReg,0
      rjmp TF_IT01
;      rjmp TF_IT00
      ;intentional fallthrough
TF_IT00:
     inc  TempReg
     sts  TweakPtr, TempReg

     add_tweak 0,1

     rjmp TF_ITx9

TF_IT01:
     inc  TempReg
     sts  TweakPtr, TempReg

     add_tweak 1,2

     rjmp TF_ITx9

TF_IT02:
     clr  TempReg
     sts  TweakPtr, TempReg

     add_tweak 2,0

;     rjmp TF_ITx9
      ;intentional fallthrough
TF_ITx9:
     lds  TempReg, RoundCnt
     inc  TempReg
     sts  RoundCnt, TempReg
     add  X3_0,TempReg
     clr  TempReg
     adc  X3_1,TempReg
     adc  X3_2,TempReg
     adc  X3_3,TempReg
     adc  X3_4,TempReg
     adc  X3_5,TempReg
     adc  X3_6,TempReg
     adc  X3_7,TempReg

     lds  TempReg, Temp

;----------- end of key injection 

;--- d = 4
;           --- j = 0
      add_0_1
;rota 26: mod 8 = 2, div 8 = 3
      rota_left_1
      rota_left_1
      eor  X1_0, X0_3
      eor  X1_1, X0_4
      eor  X1_2, X0_5
      eor  X1_3, X0_6
      eor  X1_4, X0_7
      eor  X1_5, X0_0
      eor  X1_6, X0_1
      eor  X1_7, X0_2

;           --- j = 1
      add_2_3
;rota 20: mod 8 = 4, div 8 = 2
      rota_left_3
      rota_left_3
      rota_left_3
      rota_left_3
      eor  X3_0, X2_2 
      eor  X3_1, X2_3 
      eor  X3_2, X2_4 
      eor  X3_3, X2_5 
      eor  X3_4, X2_6
      eor  X3_5, X2_7
      eor  X3_6, X2_0
      eor  X3_7, X2_1

;--- d = 5
.def  X1_0  =  r30 
.def  X1_1  =  r31 
.def  X1_2  =  r24 
.def  X1_3  =  r25     
.def  X1_4  =  r26
.def  X1_5  =  r27
.def  X1_6  =  r28
.def  X1_7  =  r29

.def  X3_0  =  r10    
.def  X3_1  =  r11
.def  X3_2  =  r12   
.def  X3_3  =  r13
.def  X3_4  =  r14
.def  X3_5  =  r15
.def  X3_6  =  r08
.def  X3_7  =  r09

;           --- j = 0
      add_0_1
;rota 53: mod 8 = 5, div 8 = 6
      rota_right_1
      rota_right_1
      rota_right_1
      eor  X1_0, X0_7
      eor  X1_1, X0_0
      eor  X1_2, X0_1
      eor  X1_3, X0_2
      eor  X1_4, X0_3
      eor  X1_5, X0_4
      eor  X1_6, X0_5
      eor  X1_7, X0_6

;           --- j = 1
      add_2_3
;rota 35: mod 8 = 3, div 8 = 4
      rota_left_3
      rota_left_3
      rota_left_3
      eor  X3_0, X2_4 
      eor  X3_1, X2_5 
      eor  X3_2, X2_6 
      eor  X3_3, X2_7 
      eor  X3_4, X2_0
      eor  X3_5, X2_1
      eor  X3_6, X2_2
      eor  X3_7, X2_3

;--- d = 6
.def  X1_0  =  r14 
.def  X1_1  =  r15 
.def  X1_2  =  r08 
.def  X1_3  =  r09     
.def  X1_4  =  r10 
.def  X1_5  =  r11
.def  X1_6  =  r12
.def  X1_7  =  r13

.def  X3_0  =  r31    
.def  X3_1  =  r24
.def  X3_2  =  r25   
.def  X3_3  =  r26
.def  X3_4  =  r27
.def  X3_5  =  r28
.def  X3_6  =  r29
.def  X3_7  =  r30 
;           --- j = 0
      add_0_1
;rota 11: mod 8 = 3, div 8 = 1
      rota_left_1
      rota_left_1
      rota_left_1
      eor  X1_0, X0_1
      eor  X1_1, X0_2
      eor  X1_2, X0_3
      eor  X1_3, X0_4
      eor  X1_4, X0_5
      eor  X1_5, X0_6
      eor  X1_6, X0_7
      eor  X1_7, X0_0

;           --- j = 1
      add_2_3
;rota 42: mod 8 = 2, div 8 = 5
      rota_left_3
      rota_left_3
      eor  X3_0, X2_5 
      eor  X3_1, X2_6 
      eor  X3_2, X2_7 
      eor  X3_3, X2_0 
      eor  X3_4, X2_1
      eor  X3_5, X2_2
      eor  X3_6, X2_3
      eor  X3_7, X2_4

;--- d = 7
.def  X1_0  =  r26     
.def  X1_1  =  r27 
.def  X1_2  =  r28 
.def  X1_3  =  r29     
.def  X1_4  =  r30 
.def  X1_5  =  r31
.def  X1_6  =  r24
.def  X1_7  =  r25

.def  X3_0  =  r13    
.def  X3_1  =  r14
.def  X3_2  =  r15   
.def  X3_3  =  r08
.def  X3_4  =  r09
.def  X3_5  =  r10
.def  X3_6  =  r11
.def  X3_7  =  r12 
;           --- j = 0
      add_0_1
;rota 59: mod 8 = 3, div 8 = 7
      rota_left_1
      rota_left_1
      rota_left_1
      eor  X1_0, X0_7
      eor  X1_1, X0_0
      eor  X1_2, X0_1
      eor  X1_3, X0_2
      eor  X1_4, X0_3
      eor  X1_5, X0_4
      eor  X1_6, X0_5
      eor  X1_7, X0_6

;           --- j = 1
      add_2_3
;rota 50: mod 8 = 2, div 8 = 6
      rota_left_3
      rota_left_3
      eor  X3_0, X2_6 
      eor  X3_1, X2_7 
      eor  X3_2, X2_0 
      eor  X3_3, X2_1 
      eor  X3_4, X2_2
      eor  X3_5, X2_3
      eor  X3_6, X2_4
      eor  X3_7, X2_5

;-------------------------- key injection
.def  X1_0  =  r15
.def  X1_1  =  r08 
.def  X1_2  =  r09 
.def  X1_3  =  r10     
.def  X1_4  =  r11 
.def  X1_5  =  r12
.def  X1_6  =  r13
.def  X1_7  =  r14    

.def  X3_0  =  r27    
.def  X3_1  =  r28
.def  X3_2  =  r29   
.def  X3_3  =  r30
.def  X3_4  =  r31
.def  X3_5  =  r24
.def  X3_6  =  r25
.def  X3_7  =  r26 


.def  TempReg = r23 ;X2_7

      sts  Temp, TempReg
      lds  TempReg, KeyPtr
      sbrc TempReg,2
      rjmp TF_IK14
      sbrc TempReg,1
      rjmp TF_IKx3
      sbrc TempReg,0
      rjmp TF_IK11
;     rjmp TF_IK10
;intentional fallthrough
TF_IK10:
.def  TempReg = r23 ;X2_7
      inc  TempReg
      sts  KeyPtr,TempReg

      add_lower_key  0,1

      lds  TempReg,Temp
.def  TempReg = r00   ;X0_0
      sts  Temp, TempReg

      add_upper_key  2,3

      rjmp TF_ITx1

TF_IK11:
.def  TempReg = r23 ;X2_7
      inc  TempReg
      sts  KeyPtr,TempReg

      add_lower_key  1,2

      lds  TempReg,Temp
.def  TempReg = r00   ;X0_0
      sts  Temp, TempReg

      add_upper_key  3,4

      rjmp TF_ITx1

TF_IKx3:
.def  TempReg = r23 ;X2_7
      sbrc TempReg,0
      rjmp TF_IK13
;     rjmp TF_IK12
;intentional fallthrough
TF_IK12:
.def  TempReg = r23 ;X2_7
      inc  TempReg
      sts  KeyPtr,TempReg

      add_lower_key  2,3

      lds  TempReg,Temp
.def  TempReg = r00   ;X0_0
      sts  Temp, TempReg

      add_upper_key  4,0

      rjmp TF_ITx1

TF_IK13:
.def  TempReg = r23 ;X2_7
      inc  TempReg
      sts  KeyPtr,TempReg

      add_lower_key  3,4

      lds  TempReg,Temp
.def  TempReg = r00   ;X0_0
      sts  Temp, TempReg

      add_upper_key  0,1

      rjmp TF_ITx1


TF_IK14:
.def  TempReg = r23 ;X2_7
      clr  TempReg
      sts  KeyPtr,TempReg

      add_lower_key  4,0

      lds  TempReg,Temp
.def  TempReg = r00   ;X0_0
      sts  Temp, TempReg

      add_upper_key  1,2

;     rjmp TF_ITx1
;intentional fallthrough

TF_ITx1:
.def  TempReg = r00   ;X0_0
      lds  TempReg,TweakPtr
      sbrc TempReg,1
      rjmp TF_IT12
      sbrc TempReg,0
      rjmp TF_IT11
;      rjmp TF_IT10
      ;intentional fallthrough
TF_IT10:
     inc  TempReg
     sts  TweakPtr, TempReg

     add_tweak 0,1

     rjmp TF_ITx8

TF_IT11:
     inc  TempReg
     sts  TweakPtr, TempReg

     add_tweak 1,2

     rjmp TF_ITx8

TF_IT12:
     clr  TempReg
     sts  TweakPtr, TempReg

     add_tweak 2,0

;     rjmp TF_ITx8
      ;intentional fallthrough
TF_ITx8:
     lds  TempReg, RoundCnt
     inc  TempReg
     sts  RoundCnt, TempReg
     add  X3_0,TempReg
     clr  TempReg
     adc  X3_1,TempReg
     adc  X3_2,TempReg
     adc  X3_3,TempReg
     adc  X3_4,TempReg
     adc  X3_5,TempReg
     adc  X3_6,TempReg
     adc  X3_7,TempReg

     mov  TempReg, r15  ;this corrects the accumulated "renames"
     mov  r15,r14
     mov  r14,r13
     mov  r13,r12
     mov  r12,r11
     mov  r11,r10
     mov  r10,r09
     mov  r09,r08
     mov  r08,TempReg

     mov  TempReg, r27
     mov  r27,r30
     mov  r30,r25
     mov  r25,r28
     mov  r28,r31
     mov  r31,r26
     mov  r26,r29
     mov  r29,r24

     lds  r24,RoundCnt
     cpi  r24,ROUNDS/4

     mov  r24,TempReg
     lds  TempReg, Temp
;----------- end of key injection 

     breq ThreeFishEnd
     jmp ThreeFishLoop

ThreeFishEnd:


     ret


;    end


