;(C)2006 wek   http://www.efton.sk
;free for personal use
;for commercial use, please contact wek@efton.sk

;implementation of SEA by F.X.Standaert et al.

;all routines use 29 registers (in this implementation: r2-r25,r26 - see variables; r27-r30 as misc. regs)
;---
;speed optimized
;Sea (encryption): 9658 cycles (incl. ret), 834 bytes (417 words)
;iSea (decryption) - same size, same speed
;---
;SeaED (enc/dec) - depending on flag T: 0=enc/1=dec
;9937 cycles (incl.ret) both ways, 906 bytes (453 words) (luxury costs, sorry...)
;---
;compromise between speed and size
;Sea2 (enc.only): 10906 cycles (incl. ret), 450 bytes (225 words)
;---

;.def   RVec = r2
;.def   LVec = r8
;.def   RKey = r14
;.def   LKey = r20

.def   RVec0 = r2
.def   RVec1 = r3
.def   RVec2 = r4 
.def   RVec3 = r5 
.def   RVec4 = r6 
.def   RVec5 = r7 
.def   LVec0 = r8
.def   LVec1 = r9
.def   LVec2 = r10
.def   LVec3 = r11
.def   LVec4 = r12
.def   LVec5 = r13
.def   RKey0 = r14
.def   RKey1 = r15
.def   RKey2 = r16
.def   RKey3 = r17
.def   RKey4 = r18
.def   RKey5 = r19
.def   LKey0 = r20
.def   LKey1 = r21
.def   LKey2 = r22
.def   LKey3 = r23
.def   LKey4 = r24
.def   LKey5 = r25

.def   Cnt  = r26

.def   YL   = r28
.def   YH   = r29
.def   ZL   = r30
.def   ZH   = r31

.include "m8def.inc"  ;just for the test to be able to define stack


.cseg
;--------------------------------------------------------- test
SeaTest:
       ldi   ZL,LOW(RAMEND)
       out   SPL,ZL
       ldi   ZH,HIGH(RAMEND)
       out   SPH,ZH

       ldi   ZL,LOW(TestTab*2)
       ldi   ZH,HIGH(TestTab*2)
       ldi   YL,LOW(2)    ;RVec
       ldi   YH,HIGH(2)
SeaTestX1:
       lpm   r0,Z+
       st    Y+,r0
       cpi   YL,LOW(2+6*4)  ;RVec
       brne  SeaTestX1
       call  Sea2
       set
       call  SeaED
       clt
       call  SeaED
       call  iSea
Stop:  jmp   Stop


TestTab:
       .db    1,0,0,0,0,0  ;RVec
       .db    0,0,0,0,0,0  ;LVec
       .db    1,0,0,0,0,0  ;RKey
       .db    0,0,0,0,0,0  ;LKey
TestTabEnd:


;====================================================== Sea (encryption)
Sea:
       ldi   Cnt,1
SeaX11:
        ;--- round 1 
       mov   r27,LVec0      ;pre-word-rotation of LVec   
       mov   LVec0,LVec5
       mov   LVec5,LVec4
       mov   LVec4,LVec3
       mov   LVec3,LVec2
       mov   LVec2,LVec1
       mov   LVec1,r27

       mov   r27,RVec0  ;+0
       add   r27,RKey0
       mov   r28,RVec1  ;+1
       add   r28,RKey1
       mov   r29,RVec2  ;+2
       add   r29,RKey2
       mov   r30,r29
       and   r30,r28
       eor   r27,r30
       mov   r30,r27
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   LVec0,r30
       mov   r30,r29
       and   r30,r27
       eor   r30,r28
       eor   LVec1,r30
       or    r30,r27
       eor   r30,r29
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   LVec2,r30

       mov   r27,RVec3  ;the same for the following 3 bytes
       add   r27,RKey3
       mov   r28,RVec4  
       add   r28,RKey4
       mov   r29,RVec5  
       add   r29,RKey5
       mov   r30,r29
       and   r30,r28
       eor   r27,r30
       mov   r30,r27
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   LVec3,r30
       mov   r30,r29
       and   r30,r27
       eor   r30,r28
       eor   LVec4,r30
       or    r30,r27
       eor   r30,r29
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   LVec5,r30

       cpi   Cnt,47            ;when halfway through, swap keys, other key schedule and other key used
       brne  SeaX12
       rjmp  SeaX21
SeaX12:

       mov   r27,RKey0         ;--- round 1 Key schedule
       add   r27,Cnt
       mov   r30,RKey2
       and   r30,RKey1
       eor   r30,r27
       mov   r27,r30      ;+0 stored for the rest of substitution
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   LKey1,r30    ;this includes the bytewise rotation (+0->+1); this needs no compensation
       mov   r30,RKey2
       and   r30,r27
       eor   r30,RKey1
       eor   LKey2,r30
       or    r30,r27
       eor   r30,RKey2
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   LKey3,r30

       mov   r30,RKey5    ;--- the same for following 3 bytes of key
       and   r30,RKey4
       eor   r30,RKey3
       mov   r27,r30      
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   LKey4,r30    
       mov   r30,RKey5
       and   r30,r27
       eor   r30,RKey4
       eor   LKey5,r30
       or    r30,r27
       eor   r30,RKey5
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   LKey0,r30
       
       inc   Cnt

        ;------- now round 2; rename R<->L both Vec and Key; 

       mov   r27,RVec0      ;pre-word-rotation of RVec   
       mov   RVec0,RVec5
       mov   RVec5,RVec4
       mov   RVec4,RVec3
       mov   RVec3,RVec2
       mov   RVec2,RVec1
       mov   RVec1,r27

       mov   r27,LVec0  ;+0
       add   r27,LKey0
       mov   r28,LVec1  ;+1
       add   r28,LKey1
       mov   r29,LVec2  ;+2
       add   r29,LKey2
       mov   r30,r29
       and   r30,r28
       eor   r27,r30
       mov   r30,r27
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   RVec0,r30
       mov   r30,r29
       and   r30,r27
       eor   r30,r28
       eor   RVec1,r30
       or    r30,r27
       eor   r30,r29
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   RVec2,r30

       mov   r27,LVec3  ;the same for the following 3 bytes
       add   r27,LKey3
       mov   r28,LVec4  
       add   r28,LKey4
       mov   r29,LVec5  
       add   r29,LKey5
       mov   r30,r29
       and   r30,r28
       eor   r27,r30
       mov   r30,r27
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   RVec3,r30
       mov   r30,r29
       and   r30,r27
       eor   r30,r28
       eor   RVec4,r30
       or    r30,r27
       eor   r30,r29
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   RVec5,r30

       mov   r27,LKey0         ;--- round 2 Key schedule
       add   r27,Cnt
       mov   r30,LKey2
       and   r30,LKey1
       eor   r30,r27
       mov   r27,r30      ;+0 stored for the rest of substitution
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   RKey1,r30    ;this includes the bytewise rotation (+0->+1); this needs no compensation
       mov   r30,LKey2
       and   r30,r27
       eor   r30,LKey1
       eor   RKey2,r30
       or    r30,r27
       eor   r30,LKey2
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   RKey3,r30

       mov   r30,LKey5    ;--- the same for following 3 bytes of key
       and   r30,LKey4
       eor   r30,LKey3
       mov   r27,r30      
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   RKey4,r30    
       mov   r30,LKey5
       and   r30,r27
       eor   r30,LKey4
       eor   RKey5,r30
       or    r30,r27
       eor   r30,LKey5
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   RKey0,r30
       
       inc   Cnt

       rjmp  SeaX11

        ;--- halfway through. Continue with swap keys, other key schedule (n-cnt), other key used
        ;--- key swap by renaming RKey<->LKey
        ;don't forget that Vec needs to be renamed too as we left the 1st part after odd nr of round
        ;
SeaX21:
       dec   Cnt              ;--- this is instead of nround-i

       mov   r27,LKey0         ;--- odd round key schedule, but key is swapped -> renamed
       add   r27,Cnt
       mov   r30,LKey2
       and   r30,LKey1
       eor   r30,r27
       mov   r27,r30      ;+0 stored for the rest of substitution
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   RKey1,r30    ;this includes the bytewise rotation (+0->+1); this needs no compensation
       mov   r30,LKey2
       and   r30,r27
       eor   r30,LKey1
       eor   RKey2,r30
       or    r30,r27
       eor   r30,LKey2
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   RKey3,r30

       mov   r30,LKey5    ;--- the same for following 3 bytes of key
       and   r30,LKey4
       eor   r30,LKey3
       mov   r27,r30      
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   RKey4,r30    
       mov   r30,LKey5
       and   r30,r27
       eor   r30,LKey4
       eor   RKey5,r30
       or    r30,r27
       eor   r30,LKey5
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   RKey0,r30
 
       ;------- now even round; rename R<->L both Vec and Key (but Key is already renamed due to swap; but the other part of key is used in part2...);
       mov   r27,RVec0      ;pre-word-rotation of RVec   
       mov   RVec0,RVec5
       mov   RVec5,RVec4
       mov   RVec4,RVec3
       mov   RVec3,RVec2
       mov   RVec2,RVec1
       mov   RVec1,r27

       mov   r27,LVec0  ;+0
       add   r27,LKey0
       mov   r28,LVec1  ;+1
       add   r28,LKey1
       mov   r29,LVec2  ;+2
       add   r29,LKey2
       mov   r30,r29
       and   r30,r28
       eor   r27,r30
       mov   r30,r27
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   RVec0,r30
       mov   r30,r29
       and   r30,r27
       eor   r30,r28
       eor   RVec1,r30
       or    r30,r27
       eor   r30,r29
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   RVec2,r30

       mov   r27,LVec3  ;the same for the following 3 bytes
       add   r27,LKey3
       mov   r28,LVec4  
       add   r28,LKey4
       mov   r29,LVec5  
       add   r29,LKey5
       mov   r30,r29
       and   r30,r28
       eor   r27,r30
       mov   r30,r27
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   RVec3,r30
       mov   r30,r29
       and   r30,r27
       eor   r30,r28
       eor   RVec4,r30
       or    r30,r27
       eor   r30,r29
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   RVec5,r30
       

       dec   Cnt

       mov   r27,RKey0      ;--- even round Key schedule - due to swap renamed LKey<->RKey
       add   r27,Cnt
       mov   r30,RKey2
       and   r30,RKey1
       eor   r30,r27
       mov   r27,r30      ;+0 stored for the rest of substitution
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   LKey1,r30    ;this includes the bytewise rotation (+0->+1); this needs no compensation
       mov   r30,RKey2
       and   r30,r27
       eor   r30,RKey1
       eor   LKey2,r30
       or    r30,r27
       eor   r30,RKey2
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   LKey3,r30

       mov   r30,RKey5    ;--- the same for following 3 bytes of key
       and   r30,RKey4
       eor   r30,RKey3
       mov   r27,r30      
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   LKey4,r30    
       mov   r30,RKey5
       and   r30,r27
       eor   r30,RKey4
       eor   LKey5,r30
       or    r30,r27
       eor   r30,RKey5
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   LKey0,r30
       
        ;--- odd round
       mov   r27,LVec0      ;pre-word-rotation of LVec   
       mov   LVec0,LVec5
       mov   LVec5,LVec4
       mov   LVec4,LVec3
       mov   LVec3,LVec2
       mov   LVec2,LVec1
       mov   LVec1,r27

       mov   r27,RVec0  ;+0
       add   r27,RKey0
       mov   r28,RVec1  ;+1
       add   r28,RKey1
       mov   r29,RVec2  ;+2
       add   r29,RKey2
       mov   r30,r29
       and   r30,r28
       eor   r27,r30
       mov   r30,r27
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   LVec0,r30
       mov   r30,r29
       and   r30,r27
       eor   r30,r28
       eor   LVec1,r30
       or    r30,r27
       eor   r30,r29
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   LVec2,r30

       mov   r27,RVec3  ;the same for the following 3 bytes
       add   r27,RKey3
       mov   r28,RVec4  
       add   r28,RKey4
       mov   r29,RVec5  
       add   r29,RKey5
       mov   r30,r29
       and   r30,r28
       eor   r27,r30
       mov   r30,r27
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   LVec3,r30
       mov   r30,r29
       and   r30,r27
       eor   r30,r28
       eor   LVec4,r30
       or    r30,r27
       eor   r30,r29
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   LVec5,r30

       cpi   Cnt,1
       breq  SeaX23
       rjmp  SeaX21
SeaX23:
       ret

;======================== iSea - inverse sea (decryption)
iSea:
       ldi   Cnt,1
iSeaX11:
        ;--- round 1 
       mov   r27,RVec0  ;+0
       add   r27,RKey0
       mov   r28,RVec1  ;+1
       add   r28,RKey1
       mov   r29,RVec2  ;+2
       add   r29,RKey2
       mov   r30,r29
       and   r30,r28
       eor   r27,r30
       mov   r30,r27
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   LVec0,r30
       mov   r30,r29
       and   r30,r27
       eor   r30,r28
       eor   LVec1,r30
       or    r30,r27
       eor   r30,r29
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   LVec2,r30

       mov   r27,RVec3  ;the same for the following 3 bytes
       add   r27,RKey3
       mov   r28,RVec4  
       add   r28,RKey4
       mov   r29,RVec5  
       add   r29,RKey5
       mov   r30,r29
       and   r30,r28
       eor   r27,r30
       mov   r30,r27
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   LVec3,r30
       mov   r30,r29
       and   r30,r27
       eor   r30,r28
       eor   LVec4,r30
       or    r30,r27
       eor   r30,r29
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   LVec5,r30

       mov   r27,LVec0      ;post-inverse-word-rotation of LVec   
       mov   LVec0,LVec1
       mov   LVec1,LVec2
       mov   LVec2,LVec3
       mov   LVec3,LVec4
       mov   LVec4,LVec5
       mov   LVec5,r27


       cpi   Cnt,47            ;when halfway through, swap keys, other key schedule and other key used
       brne  iSeaX12
       rjmp  iSeaX21
iSeaX12:

       mov   r27,RKey0         ;--- round 1 Key schedule
       add   r27,Cnt
       mov   r30,RKey2
       and   r30,RKey1
       eor   r30,r27
       mov   r27,r30      ;+0 stored for the rest of substitution
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   LKey1,r30    ;this includes the bytewise rotation (+0->+1); this needs no compensation
       mov   r30,RKey2
       and   r30,r27
       eor   r30,RKey1
       eor   LKey2,r30
       or    r30,r27
       eor   r30,RKey2
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   LKey3,r30

       mov   r30,RKey5    ;--- the same for following 3 bytes of key
       and   r30,RKey4
       eor   r30,RKey3
       mov   r27,r30      
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   LKey4,r30    
       mov   r30,RKey5
       and   r30,r27
       eor   r30,RKey4
       eor   LKey5,r30
       or    r30,r27
       eor   r30,RKey5
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   LKey0,r30
       
       inc   Cnt

        ;------- now round 2; rename R<->L both Vec and Key; 

       mov   r27,LVec0  ;+0
       add   r27,LKey0
       mov   r28,LVec1  ;+1
       add   r28,LKey1
       mov   r29,LVec2  ;+2
       add   r29,LKey2
       mov   r30,r29
       and   r30,r28
       eor   r27,r30
       mov   r30,r27
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   RVec0,r30
       mov   r30,r29
       and   r30,r27
       eor   r30,r28
       eor   RVec1,r30
       or    r30,r27
       eor   r30,r29
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   RVec2,r30

       mov   r27,LVec3  ;the same for the following 3 bytes
       add   r27,LKey3
       mov   r28,LVec4  
       add   r28,LKey4
       mov   r29,LVec5  
       add   r29,LKey5
       mov   r30,r29
       and   r30,r28
       eor   r27,r30
       mov   r30,r27
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   RVec3,r30
       mov   r30,r29
       and   r30,r27
       eor   r30,r28
       eor   RVec4,r30
       or    r30,r27
       eor   r30,r29
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   RVec5,r30

       mov   r27,RVec0      ;post-inverse-word-rotation of RVec   
       mov   RVec0,RVec1
       mov   RVec1,RVec2
       mov   RVec2,RVec3
       mov   RVec3,RVec4
       mov   RVec4,RVec5
       mov   RVec5,r27


       mov   r27,LKey0         ;--- round 2 Key schedule
       add   r27,Cnt
       mov   r30,LKey2
       and   r30,LKey1
       eor   r30,r27
       mov   r27,r30      ;+0 stored for the rest of substitution
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   RKey1,r30    ;this includes the bytewise rotation (+0->+1); this needs no compensation
       mov   r30,LKey2
       and   r30,r27
       eor   r30,LKey1
       eor   RKey2,r30
       or    r30,r27
       eor   r30,LKey2
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   RKey3,r30

       mov   r30,LKey5    ;--- the same for following 3 bytes of key
       and   r30,LKey4
       eor   r30,LKey3
       mov   r27,r30      
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   RKey4,r30    
       mov   r30,LKey5
       and   r30,r27
       eor   r30,LKey4
       eor   RKey5,r30
       or    r30,r27
       eor   r30,LKey5
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   RKey0,r30
       
       inc   Cnt

       rjmp  iSeaX11

        ;--- halfway through. Continue with swap keys, other key schedule (n-cnt), other key used
        ;--- key swap by renaming RKey<->LKey
        ;don't forget that Vec needs to be renamed too as we left the 1st part after odd nr of round
        ;
iSeaX21:
       dec   Cnt              ;--- this is instead of nround-i

       mov   r27,LKey0         ;--- odd round key schedule, but key is swapped -> renamed
       add   r27,Cnt
       mov   r30,LKey2
       and   r30,LKey1
       eor   r30,r27
       mov   r27,r30      ;+0 stored for the rest of substitution
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   RKey1,r30    ;this includes the bytewise rotation (+0->+1); this needs no compensation
       mov   r30,LKey2
       and   r30,r27
       eor   r30,LKey1
       eor   RKey2,r30
       or    r30,r27
       eor   r30,LKey2
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   RKey3,r30

       mov   r30,LKey5    ;--- the same for following 3 bytes of key
       and   r30,LKey4
       eor   r30,LKey3
       mov   r27,r30      
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   RKey4,r30    
       mov   r30,LKey5
       and   r30,r27
       eor   r30,LKey4
       eor   RKey5,r30
       or    r30,r27
       eor   r30,LKey5
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   RKey0,r30
 
       ;------- now even round; rename R<->L both Vec and Key (but Key is already renamed due to swap; but the other part of key is used in part2...);
       mov   r27,LVec0  ;+0
       add   r27,LKey0
       mov   r28,LVec1  ;+1
       add   r28,LKey1
       mov   r29,LVec2  ;+2
       add   r29,LKey2
       mov   r30,r29
       and   r30,r28
       eor   r27,r30
       mov   r30,r27
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   RVec0,r30
       mov   r30,r29
       and   r30,r27
       eor   r30,r28
       eor   RVec1,r30
       or    r30,r27
       eor   r30,r29
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   RVec2,r30

       mov   r27,LVec3  ;the same for the following 3 bytes
       add   r27,LKey3
       mov   r28,LVec4  
       add   r28,LKey4
       mov   r29,LVec5  
       add   r29,LKey5
       mov   r30,r29
       and   r30,r28
       eor   r27,r30
       mov   r30,r27
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   RVec3,r30
       mov   r30,r29
       and   r30,r27
       eor   r30,r28
       eor   RVec4,r30
       or    r30,r27
       eor   r30,r29
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   RVec5,r30
       
       mov   r27,RVec0      ;post-inverse-word-rotation of RVec   
       mov   RVec0,RVec1
       mov   RVec1,RVec2
       mov   RVec2,RVec3
       mov   RVec3,RVec4
       mov   RVec4,RVec5
       mov   RVec5,r27

       dec   Cnt

       mov   r27,RKey0      ;--- even round Key schedule - due to swap renamed LKey<->RKey
       add   r27,Cnt
       mov   r30,RKey2
       and   r30,RKey1
       eor   r30,r27
       mov   r27,r30      ;+0 stored for the rest of substitution
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   LKey1,r30    ;this includes the bytewise rotation (+0->+1); this needs no compensation
       mov   r30,RKey2
       and   r30,r27
       eor   r30,RKey1
       eor   LKey2,r30
       or    r30,r27
       eor   r30,RKey2
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   LKey3,r30

       mov   r30,RKey5    ;--- the same for following 3 bytes of key
       and   r30,RKey4
       eor   r30,RKey3
       mov   r27,r30      
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   LKey4,r30    
       mov   r30,RKey5
       and   r30,r27
       eor   r30,RKey4
       eor   LKey5,r30
       or    r30,r27
       eor   r30,RKey5
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   LKey0,r30
       
        ;--- odd round

       mov   r27,RVec0  ;+0
       add   r27,RKey0
       mov   r28,RVec1  ;+1
       add   r28,RKey1
       mov   r29,RVec2  ;+2
       add   r29,RKey2
       mov   r30,r29
       and   r30,r28
       eor   r27,r30
       mov   r30,r27
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   LVec0,r30
       mov   r30,r29
       and   r30,r27
       eor   r30,r28
       eor   LVec1,r30
       or    r30,r27
       eor   r30,r29
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   LVec2,r30

       mov   r27,RVec3  ;the same for the following 3 bytes
       add   r27,RKey3
       mov   r28,RVec4  
       add   r28,RKey4
       mov   r29,RVec5  
       add   r29,RKey5
       mov   r30,r29
       and   r30,r28
       eor   r27,r30
       mov   r30,r27
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   LVec3,r30
       mov   r30,r29
       and   r30,r27
       eor   r30,r28
       eor   LVec4,r30
       or    r30,r27
       eor   r30,r29
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   LVec5,r30

       mov   r27,LVec0      ;post-inverse-word-rotation of LVec   
       mov   LVec0,LVec1
       mov   LVec1,LVec2
       mov   LVec2,LVec3
       mov   LVec3,LVec4
       mov   LVec4,LVec5
       mov   LVec5,r27

       cpi   Cnt,1
       breq  iSeaX23
       rjmp  iSeaX21
iSeaX23:
       ret


;======================== SeaED - combined encryption/decryption (depending on flag T)
SeaED:
       ldi   Cnt,1
SeaEDX11:
        ;--- round 1 
       brts  SeaEDX15
       mov   r27,LVec0      ;pre-word-rotation of LVec   
       mov   LVec0,LVec5
       mov   LVec5,LVec4
       mov   LVec4,LVec3
       mov   LVec3,LVec2
       mov   LVec2,LVec1
       mov   LVec1,r27
SeaEDX15:
       mov   r27,RVec0  ;+0
       add   r27,RKey0
       mov   r28,RVec1  ;+1
       add   r28,RKey1
       mov   r29,RVec2  ;+2
       add   r29,RKey2
       mov   r30,r29
       and   r30,r28
       eor   r27,r30
       mov   r30,r27
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   LVec0,r30
       mov   r30,r29
       and   r30,r27
       eor   r30,r28
       eor   LVec1,r30
       or    r30,r27
       eor   r30,r29
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   LVec2,r30

       mov   r27,RVec3  ;the same for the following 3 bytes
       add   r27,RKey3
       mov   r28,RVec4  
       add   r28,RKey4
       mov   r29,RVec5  
       add   r29,RKey5
       mov   r30,r29
       and   r30,r28
       eor   r27,r30
       mov   r30,r27
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   LVec3,r30
       mov   r30,r29
       and   r30,r27
       eor   r30,r28
       eor   LVec4,r30
       or    r30,r27
       eor   r30,r29
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   LVec5,r30

       brtc  SeaEDX16
       mov   r27,LVec0      ;post-inverse-word-rotation of LVec   
       mov   LVec0,LVec1
       mov   LVec1,LVec2
       mov   LVec2,LVec3
       mov   LVec3,LVec4
       mov   LVec4,LVec5
       mov   LVec5,r27
SeaEDX16:

       cpi   Cnt,47            ;when halfway through, swap keys, other key schedule and other key used
       brne  SeaEDX12
       rjmp  SeaEDX21
SeaEDX12:

       mov   r27,RKey0         ;--- round 1 Key schedule
       add   r27,Cnt
       mov   r30,RKey2
       and   r30,RKey1
       eor   r30,r27
       mov   r27,r30      ;+0 stored for the rest of substitution
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   LKey1,r30    ;this includes the bytewise rotation (+0->+1); this needs no compensation
       mov   r30,RKey2
       and   r30,r27
       eor   r30,RKey1
       eor   LKey2,r30
       or    r30,r27
       eor   r30,RKey2
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   LKey3,r30

       mov   r30,RKey5    ;--- the same for following 3 bytes of key
       and   r30,RKey4
       eor   r30,RKey3
       mov   r27,r30      
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   LKey4,r30    
       mov   r30,RKey5
       and   r30,r27
       eor   r30,RKey4
       eor   LKey5,r30
       or    r30,r27
       eor   r30,RKey5
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   LKey0,r30
       
       inc   Cnt

        ;------- now round 2; rename R<->L both Vec and Key; 
       brts  SeaEDX17
       mov   r27,RVec0      ;pre-word-rotation of RVec   
       mov   RVec0,RVec5
       mov   RVec5,RVec4
       mov   RVec4,RVec3
       mov   RVec3,RVec2
       mov   RVec2,RVec1
       mov   RVec1,r27
SeaEDX17:

       mov   r27,LVec0  ;+0
       add   r27,LKey0
       mov   r28,LVec1  ;+1
       add   r28,LKey1
       mov   r29,LVec2  ;+2
       add   r29,LKey2
       mov   r30,r29
       and   r30,r28
       eor   r27,r30
       mov   r30,r27
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   RVec0,r30
       mov   r30,r29
       and   r30,r27
       eor   r30,r28
       eor   RVec1,r30
       or    r30,r27
       eor   r30,r29
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   RVec2,r30

       mov   r27,LVec3  ;the same for the following 3 bytes
       add   r27,LKey3
       mov   r28,LVec4  
       add   r28,LKey4
       mov   r29,LVec5  
       add   r29,LKey5
       mov   r30,r29
       and   r30,r28
       eor   r27,r30
       mov   r30,r27
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   RVec3,r30
       mov   r30,r29
       and   r30,r27
       eor   r30,r28
       eor   RVec4,r30
       or    r30,r27
       eor   r30,r29
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   RVec5,r30

       brtc  SeaEDX18
       mov   r27,RVec0      ;post-inverse-word-rotation of RVec   
       mov   RVec0,RVec1
       mov   RVec1,RVec2
       mov   RVec2,RVec3
       mov   RVec3,RVec4
       mov   RVec4,RVec5
       mov   RVec5,r27
SeaEDX18:

       mov   r27,LKey0         ;--- round 2 Key schedule
       add   r27,Cnt
       mov   r30,LKey2
       and   r30,LKey1
       eor   r30,r27
       mov   r27,r30      ;+0 stored for the rest of substitution
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   RKey1,r30    ;this includes the bytewise rotation (+0->+1); this needs no compensation
       mov   r30,LKey2
       and   r30,r27
       eor   r30,LKey1
       eor   RKey2,r30
       or    r30,r27
       eor   r30,LKey2
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   RKey3,r30

       mov   r30,LKey5    ;--- the same for following 3 bytes of key
       and   r30,LKey4
       eor   r30,LKey3
       mov   r27,r30      
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   RKey4,r30    
       mov   r30,LKey5
       and   r30,r27
       eor   r30,LKey4
       eor   RKey5,r30
       or    r30,r27
       eor   r30,LKey5
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   RKey0,r30
       
       inc   Cnt

       rjmp  SeaEDX11

        ;--- halfway through. Continue with swap keys, other key schedule (n-cnt), other key used
        ;--- key swap by renaming RKey<->LKey
        ;don't forget that Vec needs to be renamed too as we left the 1st part after odd nr of round
        ;
SeaEDX21:
       dec   Cnt              ;--- this is instead of nround-i

       mov   r27,LKey0         ;--- odd round key schedule, but key is swapped -> renamed
       add   r27,Cnt
       mov   r30,LKey2
       and   r30,LKey1
       eor   r30,r27
       mov   r27,r30      ;+0 stored for the rest of substitution
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   RKey1,r30    ;this includes the bytewise rotation (+0->+1); this needs no compensation
       mov   r30,LKey2
       and   r30,r27
       eor   r30,LKey1
       eor   RKey2,r30
       or    r30,r27
       eor   r30,LKey2
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   RKey3,r30

       mov   r30,LKey5    ;--- the same for following 3 bytes of key
       and   r30,LKey4
       eor   r30,LKey3
       mov   r27,r30      
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   RKey4,r30    
       mov   r30,LKey5
       and   r30,r27
       eor   r30,LKey4
       eor   RKey5,r30
       or    r30,r27
       eor   r30,LKey5
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   RKey0,r30
 
       ;------- now even round; rename R<->L both Vec and Key (but Key is already renamed due to swap; but the other part of key is used in part2...);
       brts  SeaEDX25
       mov   r27,RVec0      ;pre-word-rotation of RVec   
       mov   RVec0,RVec5
       mov   RVec5,RVec4
       mov   RVec4,RVec3
       mov   RVec3,RVec2
       mov   RVec2,RVec1
       mov   RVec1,r27
SeaEDX25:

       mov   r27,LVec0  ;+0
       add   r27,LKey0
       mov   r28,LVec1  ;+1
       add   r28,LKey1
       mov   r29,LVec2  ;+2
       add   r29,LKey2
       mov   r30,r29
       and   r30,r28
       eor   r27,r30
       mov   r30,r27
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   RVec0,r30
       mov   r30,r29
       and   r30,r27
       eor   r30,r28
       eor   RVec1,r30
       or    r30,r27
       eor   r30,r29
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   RVec2,r30

       mov   r27,LVec3  ;the same for the following 3 bytes
       add   r27,LKey3
       mov   r28,LVec4  
       add   r28,LKey4
       mov   r29,LVec5  
       add   r29,LKey5
       mov   r30,r29
       and   r30,r28
       eor   r27,r30
       mov   r30,r27
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   RVec3,r30
       mov   r30,r29
       and   r30,r27
       eor   r30,r28
       eor   RVec4,r30
       or    r30,r27
       eor   r30,r29
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   RVec5,r30

       brtc  SeaEDX26
       mov   r27,RVec0      ;post-inverse-word-rotation of RVec   
       mov   RVec0,RVec1
       mov   RVec1,RVec2
       mov   RVec2,RVec3
       mov   RVec3,RVec4
       mov   RVec4,RVec5
       mov   RVec5,r27
SeaEDX26:
       dec   Cnt

       mov   r27,RKey0      ;--- even round Key schedule - due to swap renamed LKey<->RKey
       add   r27,Cnt
       mov   r30,RKey2
       and   r30,RKey1
       eor   r30,r27
       mov   r27,r30      ;+0 stored for the rest of substitution
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   LKey1,r30    ;this includes the bytewise rotation (+0->+1); this needs no compensation
       mov   r30,RKey2
       and   r30,r27
       eor   r30,RKey1
       eor   LKey2,r30
       or    r30,r27
       eor   r30,RKey2
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   LKey3,r30

       mov   r30,RKey5    ;--- the same for following 3 bytes of key
       and   r30,RKey4
       eor   r30,RKey3
       mov   r27,r30      
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   LKey4,r30    
       mov   r30,RKey5
       and   r30,r27
       eor   r30,RKey4
       eor   LKey5,r30
       or    r30,r27
       eor   r30,RKey5
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   LKey0,r30
       
        ;--- odd round
       brts  SeaEDX27
       mov   r27,LVec0      ;pre-word-rotation of LVec   
       mov   LVec0,LVec5
       mov   LVec5,LVec4
       mov   LVec4,LVec3
       mov   LVec3,LVec2
       mov   LVec2,LVec1
       mov   LVec1,r27
SeaEDX27:

       mov   r27,RVec0  ;+0
       add   r27,RKey0
       mov   r28,RVec1  ;+1
       add   r28,RKey1
       mov   r29,RVec2  ;+2
       add   r29,RKey2
       mov   r30,r29
       and   r30,r28
       eor   r27,r30
       mov   r30,r27
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   LVec0,r30
       mov   r30,r29
       and   r30,r27
       eor   r30,r28
       eor   LVec1,r30
       or    r30,r27
       eor   r30,r29
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   LVec2,r30

       mov   r27,RVec3  ;the same for the following 3 bytes
       add   r27,RKey3
       mov   r28,RVec4  
       add   r28,RKey4
       mov   r29,RVec5  
       add   r29,RKey5
       mov   r30,r29
       and   r30,r28
       eor   r27,r30
       mov   r30,r27
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   LVec3,r30
       mov   r30,r29
       and   r30,r27
       eor   r30,r28
       eor   LVec4,r30
       or    r30,r27
       eor   r30,r29
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   LVec5,r30

       brtc  SeaEDX28
       mov   r27,LVec0      ;post-inverse-word-rotation of LVec   
       mov   LVec0,LVec1
       mov   LVec1,LVec2
       mov   LVec2,LVec3
       mov   LVec3,LVec4
       mov   LVec4,LVec5
       mov   LVec5,r27
SeaEDX28:
       cpi   Cnt,1
       breq  SeaEDX23
       rjmp  SeaEDX21
SeaEDX23:
       ret

;======================== Sea2 - a compromise between speed and length
Sea2:
       ldi   Cnt,1
Sea2X11:
       rcall Sea2LRound        ;--- odd round
       cpi   Cnt,47            ;when halfway through, swap keys, other key schedule and other key used
       breq  Sea2X21
       rcall Sea2LKey
       inc   Cnt
       rcall Sea2RRound        ;--- even round
       rcall Sea2RKey
       inc   Cnt
       rjmp  Sea2X11

        ;--- halfway through. Continue with swap keys, other key schedule (n-cnt), other key used
        ;--- key swap by renaming RKey<->LKey
Sea2X21:
       dec   Cnt              ;--- this is instead of nround-i
       rcall Sea2RKey
       rcall Sea2RRound
       dec   Cnt
       rcall Sea2LKey
       rcall Sea2LRound
       cpi   Cnt,1
       brne  Sea2X21
       ret

;------------ parts of Sea2
Sea2LRound:
       mov   r27,LVec0      ;pre-word-rotation of LVec   
       mov   LVec0,LVec5
       mov   LVec5,LVec4
       mov   LVec4,LVec3
       mov   LVec3,LVec2
       mov   LVec2,LVec1
       mov   LVec1,r27

       mov   r27,RVec0  ;+0
       add   r27,RKey0
       mov   r28,RVec1  ;+1
       add   r28,RKey1
       mov   r29,RVec2  ;+2
       add   r29,RKey2
       mov   r30,r29
       and   r30,r28
       eor   r27,r30
       mov   r30,r27
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   LVec0,r30
       mov   r30,r29
       and   r30,r27
       eor   r30,r28
       eor   LVec1,r30
       or    r30,r27
       eor   r30,r29
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   LVec2,r30

       mov   r27,RVec3  ;the same for the following 3 bytes
       add   r27,RKey3
       mov   r28,RVec4  
       add   r28,RKey4
       mov   r29,RVec5  
       add   r29,RKey5
       mov   r30,r29
       and   r30,r28
       eor   r27,r30
       mov   r30,r27
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   LVec3,r30
       mov   r30,r29
       and   r30,r27
       eor   r30,r28
       eor   LVec4,r30
       or    r30,r27
       eor   r30,r29
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   LVec5,r30

       ret


Sea2RRound:                          
       mov   r27,RVec0      ;pre-word-rotation of RVec   
       mov   RVec0,RVec5
       mov   RVec5,RVec4
       mov   RVec4,RVec3
       mov   RVec3,RVec2
       mov   RVec2,RVec1
       mov   RVec1,r27

       mov   r27,LVec0  ;+0
       add   r27,LKey0
       mov   r28,LVec1  ;+1
       add   r28,LKey1
       mov   r29,LVec2  ;+2
       add   r29,LKey2
       mov   r30,r29
       and   r30,r28
       eor   r27,r30
       mov   r30,r27
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   RVec0,r30
       mov   r30,r29
       and   r30,r27
       eor   r30,r28
       eor   RVec1,r30
       or    r30,r27
       eor   r30,r29
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   RVec2,r30

       mov   r27,LVec3  ;the same for the following 3 bytes
       add   r27,LKey3
       mov   r28,LVec4  
       add   r28,LKey4
       mov   r29,LVec5  
       add   r29,LKey5
       mov   r30,r29
       and   r30,r28
       eor   r27,r30
       mov   r30,r27
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   RVec3,r30
       mov   r30,r29
       and   r30,r27
       eor   r30,r28
       eor   RVec4,r30
       or    r30,r27
       eor   r30,r29
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   RVec5,r30

       ret

Sea2LKey:
       mov   r27,RKey0         ;--- round 1 Key schedule
       add   r27,Cnt
       mov   r30,RKey2
       and   r30,RKey1
       eor   r30,r27
       mov   r27,r30      ;+0 stored for the rest of substitution
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   LKey1,r30    ;this includes the bytewise rotation (+0->+1); this needs no compensation
       mov   r30,RKey2
       and   r30,r27
       eor   r30,RKey1
       eor   LKey2,r30
       or    r30,r27
       eor   r30,RKey2
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   LKey3,r30

       mov   r30,RKey5    ;--- the same for following 3 bytes of key
       and   r30,RKey4
       eor   r30,RKey3
       mov   r27,r30      
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   LKey4,r30    
       mov   r30,RKey5
       and   r30,r27
       eor   r30,RKey4
       eor   LKey5,r30
       or    r30,r27
       eor   r30,RKey5
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   LKey0,r30

       ret

Sea2RKey:
       mov   r27,LKey0         ;--- round 2 Key schedule
       add   r27,Cnt
       mov   r30,LKey2
       and   r30,LKey1
       eor   r30,r27
       mov   r27,r30      ;+0 stored for the rest of substitution
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   RKey1,r30    ;this includes the bytewise rotation (+0->+1); this needs no compensation
       mov   r30,LKey2
       and   r30,r27
       eor   r30,LKey1
       eor   RKey2,r30
       or    r30,r27
       eor   r30,LKey2
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   RKey3,r30

       mov   r30,LKey5    ;--- the same for following 3 bytes of key
       and   r30,LKey4
       eor   r30,LKey3
       mov   r27,r30      
       clc                ;rr
       sbrc  r30,0
       sec
       ror   r30
       eor   RKey4,r30    
       mov   r30,LKey5
       and   r30,r27
       eor   r30,LKey4
       eor   RKey5,r30
       or    r30,r27
       eor   r30,LKey5
       clc                ;rl
       sbrc  r30,7
       sec
       rol   r30
       eor   RKey0,r30

       ret
;=======================================================

