]> git.cryptolib.org Git - avr-crypto-lib.git/blob - camellia/camellia-asm.S
621bd7e4fb420f195ec7495d568e9872ae3c2f6a
[avr-crypto-lib.git] / camellia / camellia-asm.S
1 /* camellia-asm.S */
2 /*
3     This file is part of the AVR-Crypto-Lib.
4     Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
5
6     This program is free software: you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation, either version 3 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19 /* 
20  * File:        camellis-asm.S
21  * Author:      Daniel Otte
22  * Date:        2006-11-10
23  * License:     GPLv3 or later
24  * Description: Implementation of the camellia block cipher algorithm.
25  * 
26  */
27  
28 .macro SWAP_R A, B
29         eor \A, \B
30         eor \B, \A
31         eor \A, \B
32 .endm    
33  
34 .macro precall
35         /* push r18 - r27, r30 - r31*/
36         push r0
37         push r1
38         push r18
39         push r19
40         push r20
41         push r21
42         push r22
43         push r23
44         push r24
45         push r25
46         push r26
47         push r27
48         push r30
49         push r31
50         clr r1
51 .endm
52
53 .macro postcall
54         pop r31
55         pop r30
56         pop r27
57         pop r26
58         pop r25
59         pop r24
60         pop r23
61         pop r22
62         pop r21
63         pop r20
64         pop r19
65         pop r18
66         pop r1
67         pop r0
68 .endm
69
70
71 .macro hexdump length
72         push r27
73         push r26
74         ldi r25, '\r'
75         mov r24, r25
76         call uart_putc
77         ldi r25, '\n'
78         mov r24, r25
79         call uart_putc
80         pop r26
81         pop r27
82         movw r24, r26
83 .if \length > 16
84         ldi r22, lo8(16)
85         ldi r23, hi8(16)
86         push r27
87         push r26
88         call uart_hexdump
89         pop r26
90         pop r27
91         adiw r26, 16
92         hexdump \length-16
93 .else
94         ldi r22, lo8(\length)
95         ldi r23, hi8(\length)
96         call uart_hexdump
97 .endif
98 .endm
99
100 /* X points to Block */
101 .macro dbg_hexdump length
102         precall
103         hexdump \length
104         postcall
105 .endm
106  
107 SPL = 0x3D
108 SPH = 0x3E
109 SREG = 0x3F
110 NULLr = 1
111  
112  
113 camellia_sbox:
114 .byte   112, 130,  44, 236, 179,  39, 192, 229, 228, 133,  87,  53, 234,  12, 174,  65
115 .byte    35, 239, 107, 147,  69,  25, 165,  33, 237,  14,  79,  78,  29, 101, 146, 189
116 .byte   134, 184, 175, 143, 124, 235,  31, 206,  62,  48, 220,  95,  94, 197,  11,  26
117 .byte   166, 225,  57, 202, 213,  71,  93,  61, 217,   1,  90, 214,  81,  86, 108,  77
118 .byte   139,  13, 154, 102, 251, 204, 176,  45, 116,  18,  43,  32, 240, 177, 132, 153
119 .byte   223,  76, 203, 194,  52, 126, 118,   5, 109, 183, 169,  49, 209,  23,   4, 215
120 .byte    20,  88,  58,  97, 222,  27,  17,  28,  50,  15, 156,  22,  83,  24, 242,  34
121 .byte   254,  68, 207, 178, 195, 181, 122, 145,  36,   8, 232, 168,  96, 252, 105,  80
122 .byte   170, 208, 160, 125, 161, 137,  98, 151,  84,  91,  30, 149, 224, 255, 100, 210
123 .byte    16, 196,   0,  72, 163, 247, 117, 219, 138,   3, 230, 218,   9,  63, 221, 148
124 .byte   135,  92, 131,   2, 205,  74, 144,  51, 115, 103, 246, 243, 157, 127, 191, 226
125 .byte    82, 155, 216,  38, 200,  55, 198,  59, 129, 150, 111,  75,  19, 190,  99,  46
126 .byte   233, 121, 167, 140, 159, 110, 188, 142,  41, 245, 249, 182,  47, 253, 180,  89
127 .byte   120, 152,   6, 106, 231,  70, 113, 186, 212,  37, 171,  66, 136, 162, 141, 250
128 .byte   114,   7, 185,  85, 248, 238, 172,  10,  54,  73,  42, 104,  60,  56, 241, 164
129 .byte    64,  40, 211, 123, 187, 201,  67, 193,  21, 227, 173, 244, 119, 199, 128, 158
130
131 //.global camellia_sigma
132 /*
133 camellia_sigma:
134 .quad   0xA09E667F3BCC908B
135 .quad   0xB67AE8584CAA73B2
136 .quad   0xC6EF372FE94F82BE
137 .quad   0x54FF53A5F1D36F1C
138 .quad   0x10E527FADE682D1D
139 .quad   0xB05688C2B3E6C1FD      
140 */
141
142
143
144 /* uint8_t camellia_s1(uint8_t b) */
145 .global camellia_s1
146 camellia_s1:
147         ldi r30, lo8(camellia_sbox)
148         ldi r31, hi8(camellia_sbox)
149         add r30, r24
150         adc r31, NULLr
151         lpm r24, Z
152         clr r25
153         ret
154
155 .global camellia_s2
156 camellia_s2:
157         ldi r30, lo8(camellia_sbox)
158         ldi r31, hi8(camellia_sbox)
159         add r30, r24
160         adc r31, NULLr
161         lpm r24, Z
162         lsl r24
163         adc r24, NULLr
164         clr r25
165         ret
166
167 .global camellia_s3
168 camellia_s3:
169         ldi r30, lo8(camellia_sbox)
170         ldi r31, hi8(camellia_sbox)
171         add r30, r24
172         adc r31, NULLr
173         lpm r24, Z
174         bst r24, 0
175         lsr r24
176         bld r24, 7
177         clr r25
178         ret
179
180 .global camellia_s4
181 camellia_s4:
182         ldi r30, lo8(camellia_sbox)
183         ldi r31, hi8(camellia_sbox)
184         lsl r24
185         adc r24, NULLr
186         add r30, r24
187         adc r31, NULLr
188         lpm r24, Z
189         clr r25
190         ret
191
192 .global camellia_s
193 /* uint64_t camellia_s(uint64_t d){
194         #define D ((uint8_t*)(&d))
195         D[7] = camellia_s1(D[7]); // MSB
196         D[6] = camellia_s2(D[6]);
197         D[5] = camellia_s3(D[5]);
198         D[4] = camellia_s4(D[4]);
199         
200         D[3] = camellia_s2(D[3]);
201         D[2] = camellia_s3(D[2]);
202         D[1] = camellia_s4(D[1]);
203         D[0] = camellia_s1(D[0]); // LSB
204         #undef D
205         return d;
206 }*/
207 ; parameters
208 ; d: r18-r25 (r18 is LSB)
209 camellia_s:
210         movw r26, r24   ; backup r24,r25 -> X
211         clr r25
212         rcall camellia_s2
213         mov r26, r24
214
215         mov r24, r27
216         rcall camellia_s1
217         mov r27, r24
218          
219         mov r24, r23
220         rcall camellia_s3
221         mov r23, r24
222         
223         mov r24, r22
224         rcall camellia_s4
225         mov r22, r24
226
227         mov r24, r21
228         rcall camellia_s2
229         mov r21, r24
230         
231         mov r24, r20
232         rcall camellia_s3
233         mov r20, r24
234         
235         mov r24, r19
236         rcall camellia_s4
237         mov r19, r24
238
239
240         mov r24, r18
241         rcall camellia_s1
242         mov r18, r24
243                 
244         movw r24, r26
245         ret
246         
247 ;##############################################################################
248 /* uint64_t camellia_p(uint64_t d) */
249 ; param: r18-r25 (r18 is LSB)
250 z1 = 25
251 z2 = 24
252 z3 = 23
253 z4 = 22
254 z5 = 21
255 z6 = 20
256 z7 = 19
257 z8 = 18
258
259 .global camellia_p
260 camellia_p:
261         eor z1, z6
262         eor z2, z7
263         eor z3, z8
264         eor z4, z5
265         eor z5, z3
266         eor z6, z4
267         eor z7, z1
268         eor z8, z2
269     ;---------
270         eor z1, z8
271         eor z2, z5
272         eor z3, z6
273         eor z4, z7
274         eor z5, z4
275         eor z6, z1
276         eor z7, z2
277         eor z8, z3
278     ;---------
279         movw r26, z8
280         movw r30, z6 ; backup z5 bis z8
281         movw z8, z4
282         movw z6, z2
283         movw z4, r26
284         movw z2, r30
285         ret
286         
287
288 ;##############################################################################
289
290 /* uint64_t camellia_f(uint64_t x, uint64_t k) */       
291 ; param x: r18-r25
292 ; param k: r10-r17
293 .global camellia_f
294 camellia_f:
295         eor r18, r10
296         eor r19, r11
297         eor r20, r12
298         eor r21, r13
299         eor r22, r14
300         eor r23, r15
301         eor r24, r16
302         eor r25, r17
303         rcall camellia_s
304         rcall camellia_p
305         ret
306         
307 ;##############################################################################
308
309 /* uint64_t camellia_fl(uint64_t x, uint64_t k) */
310 ; param x: r18-r25              xl: r22-r25, xr: r18-r21
311 ; param k: r10-r17              kl: r14-r17, kr: r10-r13
312 kl1 = 14
313 kl2 = 15
314 kl3 = 16
315 kl4 = 17
316 kr1 = 10
317 kr2 = 11
318 kr3 = 12
319 kr4 = 13
320 xr1 = 18
321 xr2 = 19
322 xr3 = 20
323 xr4 = 21
324 xl1 = 22
325 xl2 = 23
326 xl3 = 24
327 xl4 = 25
328 .global camellia_fl
329 camellia_fl:
330         and kl1, xl1
331         and kl2, xl2
332         and kl3, xl3
333         and kl4, xl4
334         mov r26, kl4
335         rol r26
336         rol kl1
337         rol kl2
338         rol kl3
339         rol kl4
340         eor xr1, kl1
341         eor xr2, kl2
342         eor xr3, kl3
343         eor xr4, kl4
344         // that was part one
345         or kr1, xr1
346         or kr2, xr2
347         or kr3, xr3
348         or kr4, xr4     
349         eor xl1, kr1
350         eor xl2, kr2
351         eor xl3, kr3
352         eor xl4, kr4
353         ret
354         
355 ;##############################################################################
356
357 /* uint64_t camellia_fl_inv(uint64_t y, uint64_t k) */
358 ; param y: r18-r25              yl: r22-r25, yr: r18-r21
359 ; param k: r10-r17              kl: r14-r17, kr: r10-r13
360 kl1 = 14
361 kl2 = 15
362 kl3 = 16
363 kl4 = 17
364 kr1 = 10
365 kr2 = 11
366 kr3 = 12
367 kr4 = 13
368 yr1 = 18
369 yr2 = 19
370 yr3 = 20
371 yr4 = 21
372 yl1 = 22
373 yl2 = 23
374 yl3 = 24
375 yl4 = 25
376 .global camellia_fl_inv
377 camellia_fl_inv:
378         or kr1, yr1
379         or kr2, yr2
380         or kr3, yr3
381         or kr4, yr4
382         eor yl1, kr1
383         eor yl2, kr2
384         eor yl3, kr3
385         eor yl4, kr4
386         // the first one is done
387         and kl1, yl1
388         and kl2, yl2
389         and kl3, yl3
390         and kl4, yl4    
391         mov r26, kl4
392         rol r26
393         rol kl1
394         rol kl2
395         rol kl3
396         rol kl4
397         eor yr1, kl1
398         eor yr2, kl2
399         eor yr3, kl3
400         eor yr4, kl4
401         ret
402
403 ;##############################################################################
404 ; param s: r24-r25
405 ; param q: r22
406 B1 = 18
407 B2 = 19
408 .global camellia128_keyop_rot15
409 camellia128_keyop_rot15:
410         movw r30, r24 ; Z points at LSB of kl            ;-- 0
411         ldi r22, 2              
412 2:      adiw r30, 15                                     ;-- 15
413         ld  r21, Z
414         ld  r20, -Z                                      ;-- 14
415         movw B1, r20 ; store Backup of the 2 MSB of kl
416         ror r20
417
418         ldi r21, 14
419 1:      ld r20, -Z                                       ;-- 13..0
420         ror r20
421         std Z+2, r20                                     ;-- (15..2)
422         dec r21
423         brne 1b
424         
425         ror B2
426         ror B1
427         st Z+, B1                                        ;-- 1
428         st Z, B2
429         adiw r30, 15                                     ;-- 16
430         
431         dec r22
432         brne 2b
433         ret
434
435 ;##############################################################################
436 ; param s: r24-r25
437 ; param q: r22
438 .global camellia128_keyop_rot17
439 camellia128_keyop_rot17:
440         push r8
441         push r9
442         push r10
443         push r11
444         push r12
445         push r13
446         push r14
447         push r15
448         push r16
449         push r17
450         clt
451         movw r30, r24
452         clr r27
453 2:      ldi r26, 8
454         mov r1, r26
455         lsl r1  ; r1=16
456         ;push r1
457         ; load 128bit value
458         ldd r0, Z+15
459         rol r0
460 1:      ld r0, Z+
461         rol r0
462         st X+, r0
463         dec r1
464         brne 1b
465         
466         st -Z, 21
467         st -Z, 20
468         st -Z, 19
469         st -Z, 18
470         st -Z, 17
471         st -Z, 16
472         st -Z, 15
473         st -Z, 14 ;--
474         st -Z, 13
475         st -Z, 12
476         st -Z, 11
477         st -Z, 10
478         st -Z, 9
479         st -Z, 8
480         st -Z, 23
481         st -Z, 22
482         
483         brts 2f
484         set
485         adiw r30, 16
486         rjmp 2b
487 2:      
488         pop r17
489         pop r16
490         pop r15
491         pop r14
492         pop r13
493         pop r12
494         pop r11
495         pop r10
496         pop r9
497         pop r8 
498         ret
499
500 ;##############################################################################
501 ; param s: r24-r25
502 ; param q: r22
503 .global camellia128_keyop
504 camellia128_keyop:
505         cpi r22, 1
506         breq camellia128_keyop_rot17
507         rjmp camellia128_keyop_rot15
508         
509 ;##############################################################################
510 ; param s: r24-r25
511 ; param q: r22
512 B1 = 18
513 B2 = 19
514 .global camellia128_keyop_inv_rot15
515 camellia128_keyop_inv_rot15:
516         movw r30, r24 ; Z points at LSB of kl                ;-- 0
517         movw r26, r24 ; X also
518         ldi r22, 2              
519 2:                                                           ;-- 0
520         ld  r20, Z+                                          ;-- 0/1
521         ld  r21, Z+                                          ;-- 1/2
522         movw B1, r20 ; store Backup of the 2 LSB of kl
523         rol r21
524
525         ldi r20, 14
526 1:      ld r21, Z+                                           ;-- 2/14..3/16
527         rol r21
528         st X+, r21                                           ;-- (0..13)/(1..14)
529         dec r20
530         brne 1b
531         
532         rol B1
533         rol B2
534         st X+, B1                                            ;-- 14/15
535         st X+, B2                                            ;-- 15/16
536         
537         dec r22
538         brne 2b
539         ret
540         
541 ;##############################################################################
542 ; param s: r24-r25
543 ; param q: r22
544 .global camellia128_keyop_inv_rot17
545 camellia128_keyop_inv_rot17:
546         push r8
547         push r9
548         push r10
549         push r11
550         push r12
551         push r13
552         push r14
553         push r15
554         push r16
555         push r17
556         clt
557         movw r30, r24
558         clr r27
559 2:      ldi r26, 8
560         mov r1, r26
561         lsl r1  ; r1=16
562         ; load 128bit value
563         
564         ld  r0, Z
565         adiw r30, 16
566         ror r0
567 1:      ld r0, -Z
568         ror r0
569         st X+, r0
570         dec r1
571         brne 1b
572         
573         st Z+, 21
574         st Z+, 20
575         st Z+, 19
576         st Z+, 18
577         st Z+, 17
578         st Z+, 16
579         st Z+, 15
580         st Z+, 14 ;--
581         st Z+, 13
582         st Z+, 12
583         st Z+, 11
584         st Z+, 10
585         st Z+, 9
586         st Z+, 8
587         st Z+, 23
588         st Z+, 22
589         
590         brts 2f
591         set
592 ;       adiw r30, 16
593         rjmp 2b
594 2:      
595         pop r17
596         pop r16
597         pop r15
598         pop r14
599         pop r13
600         pop r12
601         pop r11
602         pop r10
603         pop r9
604         pop r8 
605         ret
606
607 ;##############################################################################
608 ; param s: r24-r25
609 ; param q: r22
610 .global camellia128_keyop_inv
611 camellia128_keyop_inv:
612         cpi r22, 1
613         breq camellia128_keyop_inv_rot17
614         rjmp camellia128_keyop_inv_rot15
615         
616 ;##############################################################################
617 ; param p: r24-r25      pointer to data
618 ; param l: r22          length of word
619 .global change_endian
620 change_endian:
621         movw r26, r24
622         movw r30, r24
623         add r30, r22
624         adc     r31, r1
625         lsr r22
626 1:
627         ld r20,  X
628         ld r21, -Z      
629         st X+, r21
630         st Z,  r20
631         dec r22
632         brne 1b
633         ret
634
635 ;##############################################################################
636         
637 #define SEL_KA 1
638 #define SEL_KL 0
639 #define KEY_POSTC1              0x00
640 #define KEY_POSTC2              0x01
641 #define KEY_INC2                0x02
642 #define KEY_DIR                 0x04
643 #define KEY_DIR_NORM    0x00
644 #define KEY_DIR_INV             0x04
645 #define KEY_AMMOUNT             0x08 
646 #define KEY_ROL17               0x08
647 #define KEY_ROL15               0x00
648 /*
649 void camellia_6rounds(camellia128_ctx_t *s, uint64_t *bl, uint64_t *br, uint8_t roundop, uint8_t keychoice){
650         uint8_t i;
651         uint64_t *k[4];
652         k[0] = &(s->kll);
653         k[1] = &(s->klr);
654         k[2] = &(s->kal);
655         k[3] = &(s->kar);
656         for(i=0; i<3; ++i){ / * each cycle * /
657                 br[0] ^= camellia_f(bl[0],*(k[(keychoice&1)*2+((roundop&KEY_DIR)?1:0)]));
658                 keychoice >>= 1;
659                 
660                 if((i == 1) && (roundop&KEY_INC2)){
661                         ((roundop&KEY_DIR)?camellia128_keyop_inv:camellia128_keyop)(s,(roundop&KEY_AMMOUNT)?1:-1);
662                 }
663                 
664                 bl[0] ^= camellia_f(br[0],*(k[(keychoice&1)*2+((roundop&KEY_DIR)?0:1)]));
665                 keychoice >>= 1;
666                 
667                 / * check if we should do some keyop * /
668                 if((i == (roundop&1)) && (!(roundop&KEY_INC2)) ){
669                         ((roundop&KEY_DIR)?camellia128_keyop_inv:camellia128_keyop)(s,(roundop&KEY_AMMOUNT)?1:-1);
670                         / * isn't it fuckin nice what we can do in C?! * /
671                 }
672         }
673 }
674 */
675 ; param s:  r24-r25
676 ; param bl: r22-r23
677 ; param br: r20-r21
678 ; param roundop: r18
679 ; param keychoice: r16  
680 s1 = 24
681 s2 = 25
682 bl1 = 22
683 bl2 = 23
684 br1 = 20
685 br2 = 22
686 xro = 18
687 kc = 16 
688 xro_sec = 17
689 br1_sec = 10
690 br2_sec = 11
691 bl1_sec = 12
692 bl2_sec = 13
693 s1_sec = 14
694 t = 9
695 loop_cnt = 8
696 keyop_time = 7
697
698 .global camellia_6rounds
699 camellia_6rounds:
700         push r17
701         push r16
702         push r15
703         push r14
704         push r13
705         push r12
706         push r11
707         push r10
708         push r9
709         push r8
710         push r7
711         
712         ldi r17, 6
713         mov loop_cnt, r17
714         mov xro_sec,  xro
715         movw br1_sec, br1
716         movw bl1_sec, bl1
717         movw s1_sec, s1
718         clr keyop_time
719         inc keyop_time
720         sec
721         rol keyop_time // keyop_time == 3
722         SBRC xro, 1 // KEY_INC2
723          rjmp 1f
724         SBRS xro, 0 // KEY_POSTC1
725          inc keyop_time
726         SBRS xro, 0 // KEY_POSTC1
727          inc keyop_time
728         rjmp 2f
729 1:      inc keyop_time
730 2:
731 main_loop:
732         /* now we load the key to r18-r25 */
733         movw r26, s1_sec
734         SBRC kc, 0              /* select between KA and KL */
735          adiw r26, 16
736         SBRC xro_sec, 2 // KEY_DIR
737          rjmp 2f
738         SBRS loop_cnt, 0 /* enc */
739          adiw r26,  8
740         rjmp 3f 
741 2:      SBRC loop_cnt, 0  /* dec */
742          adiw r26,  8
743         rjmp 3f 
744 3:
745         lsr kc
746         ld r18, X+
747         ld r19, X+
748         ld r20, X+
749         ld r21, X+
750         ld r22, X+
751         ld r23, X+
752         ld r24, X+
753         ld r25, X+
754         /* now we xor bl in */
755         movw r26, bl1_sec
756         ld r0, X+
757         eor r18, r0
758         ld r0, X+
759         eor r19, r0
760         ld r0, X+
761         eor r20, r0
762         ld r0, X+
763         eor r21, r0
764         ld r0, X+
765         eor r22, r0
766         ld r0, X+
767         eor r23, r0
768         ld r0, X+
769         eor r24, r0
770         ld r0, X+
771         eor r25, r0
772         /* f(x,k) = p(s(x xor k)) ; xor is done */
773         call camellia_s;
774         call camellia_p;
775         
776 //      in r26, SPL
777 //      in r27, SPH
778 //      sbiw r26, 9
779 //      dbg_hexdump 10 
780         /* now we have to xor the result into br */
781         clr r31
782         ldi r30, 18
783         movw r26, br1_sec
784 ;       ldi r1, 8 ;-- this won't work
785         clr r1
786         sec
787         ror r1
788         swap r1
789 1:       ld r0, X
790          ld t, Z+
791          eor r0, t
792          st X+, r0
793         dec r1
794         brne 1b
795         
796         /* check for keyop */
797         cp loop_cnt, keyop_time
798         brne 3f
799         movw s1, s1_sec
800         ldi r22, 1
801         SBRS xro_sec, 3 // KEY_ROL17
802          neg r22
803         SBRS xro_sec, 2 // KEY_DIR
804          rjmp 2f
805         rcall camellia128_keyop_inv
806         rjmp 3f 
807 2:      rcall camellia128_keyop
808 3:      /* loop back */
809         SWAP_R br1_sec, bl1_sec
810         SWAP_R br2_sec, bl2_sec
811         dec loop_cnt
812         breq 2f
813         rjmp main_loop
814 2:
815         pop r7
816         pop r8
817         pop r9
818         pop r10
819         pop r11
820         pop r12
821         pop r13
822         pop r14
823         pop r15
824         pop r16
825         pop r17
826         ret
827         
828 ;##############################################################################
829 /*      
830 void camellia128_init(camellia128_ctx_t *s, uint8_t *key){
831         uint8_t i;
832         s->kll = 0; //((uint64_t*)key)[0];
833         
834         / * load the key, endian-adjusted, to kll,klr * /
835         for(i=0; i<8; ++i){
836                 s->kll <<= 8;
837                 s->kll |= *key++;
838         }
839         for(i=0; i<8; ++i){
840                 s->klr <<= 8;
841                 s->klr |= *key++;
842         }
843         
844         s->kal = s->kll;
845         s->kar = s->klr;
846         
847         s->kar ^= camellia_f(s->kal, camellia_sigma[0]);
848         s->kal ^= camellia_f(s->kar, camellia_sigma[1]);
849         
850         s->kal ^= s->kll;
851         s->kar ^= s->klr;
852         
853         s->kar ^= camellia_f(s->kal, camellia_sigma[2]);
854         s->kal ^= camellia_f(s->kar, camellia_sigma[3]);
855         / * * /
856 //      uart_putstr("\n\r----------------init finished--------------------");
857 }       
858 */      
859 /*
860 X64_xor_in:
861         ld r0, X+ 
862         eor r18, r0
863         ld r0, X+ 
864         eor r19, r0
865         ld r0, X+ 
866         eor r20, r0
867         ld r0, X+ 
868         eor r21, r0
869         ld r0, X+ 
870         eor r22, r0
871         ld r0, X+ 
872         eor r23, r0
873         ld r0, X+ 
874         eor r24, r0
875         ld r0, X+ 
876         eor r25, r0
877         ret
878
879 X64_load:
880         ld r18, X+
881         ld r19, X+
882         ld r20, X+
883         ld r21, X+
884         ld r22, X+
885         ld r23, X+
886         ld r24, X+
887         ld r25, X+
888         ret
889
890 Y64_load_xor_store:
891         ld r0, Y
892         eor r18, r0
893         st Y+, r18
894         ld r0, Y
895         eor r19, r0
896         st Y+, r19
897         ld r0, Y
898         eor r20, r0
899         st Y+, r20
900         ld r0, Y
901         eor r21, r0
902         st Y+, r21
903         ld r0, Y
904         eor r22, r0
905         st Y+, r22
906         ld r0, Y
907         eor r23, r0
908         st Y+, r23
909         ld r0, Y
910         eor r24, r0
911         st Y+, r24
912         ld r0, Y
913         eor r25, r0
914         st Y+, r25
915         ret     
916         
917 ; param s:  r24-r25
918 ; param *k: r22-r23
919 //.global camellia128_init
920 camellia128_init:       
921         push r29
922         push r28
923         movw r30, r24 ; Z is statepointer
924         movw r26, r22 ; X is keypointer
925         clr r29
926         ldi r28, 18
927 //      / * load key into kl, ka and kal to r18:r25 * /
928         adiw r26, 128/8 ;-- 16
929         ldi r16, (128/8)-1
930 1:      ld r17, -X
931         std Z+(128/8), r17
932         st Z+, r17
933         sbrs r16, 3
934         st Y+, r17              ; this should only be done the last 8 rounds 0<=r16<=7
935         dec r16
936         brpl 1b
937 //      / * step 1 * /
938         ldi r26, lo8(camellia_sigma)
939         ldi r27, hi8(camellia_sigma)
940         rcall X64_xor_in
941         rcall camellia_s
942         rcall camellia_p        // / * f(x,k) is done * /
943         sbiw r30, 128/8
944         movw r28, r30 ; Z&Y point on kar now
945         call Y64_load_xor_store
946
947 //      / * step 2 now * /
948         rcall X64_xor_in
949         rcall camellia_s
950         rcall camellia_p        // / * f(x,k) is done * /
951         rcall Y64_load_xor_store
952         
953 //      / * now the xor part (kl and kr) * /
954         sbiw r30, 128/8         ; Z points to klr
955         ldi r16, 128/8
956 1:      ld  r0, Z+
957         ldd r1, Z+(128/8)-1
958         eor r0, r1
959         std Z+(128/8)-1, r0 
960         dec r16
961         brne 1b
962         
963 //      / * now s->kar ^= camellia_f(s->kal, camellia_sigma[2]); * /    
964         rcall X64_load          ; load sigma[2]
965         movw r26, r28           ; X&Y point at kal
966         rcall X64_xor_in
967         rcall camellia_s
968         rcall camellia_p
969         sbiw r28, 128/8/2       ; Y points at kar
970         rcall Y64_load_xor_store
971         
972 //      / * now s->kal ^= camellia_f(s->kar, camellia_sigma[3]); * /
973         sbiw r26, 128/8         ;
974         rcall X64_load          ; load kar
975         ldi r26, lo8(camellia_sigma+3*8)
976         ldi r27, hi8(camellia_sigma+3*8)
977         rcall X64_xor_in                ; xor sigma[3] in
978         rcall camellia_s
979         rcall camellia_p
980         rcall Y64_load_xor_store
981         
982         pop r28
983         pop r29
984         ret
985         
986 //*/    
987         
988         
989         
990
991
992
993
994
995
996