]> git.cryptolib.org Git - avr-crypto-lib.git/blob - threefish1024_enc_asm.S
38f85ed099c8e14e05c8f4e65ada3038a869a02f
[avr-crypto-lib.git] / threefish1024_enc_asm.S
1 /* threefish1024_enc_asm.S */
2 /*
3     This file is part of the AVR-Crypto-Lib.
4     Copyright (C) 2009  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  * \author  Daniel Otte
21  * \email   daniel.otte@rub.de
22  * \date    2009-03-24
23  * \license GPLv3 or later
24  */
25
26 #include "avr-asm-macros.S"
27
28 /******************************************************************************/
29 A0 = 14
30 A1 = 15
31 A2 = 16
32 A3 = 17
33 A4 = 18
34 A5 = 19
35 A6 = 20
36 A7 = 21
37 /*
38 #define THREEFISH_KEY_CONST 0x5555.5555.5555.5555.LL / * 2**64/3 * /
39
40 #define K(s) (((uint64_t*)key)[(s)])
41 #define T(s) (((uint64_t*)tweak)[(s)])
42 void threefish1024_init(const void *key, const void *tweak, threefish512_ctx_t *ctx){
43         memcpy(ctx->k, key, 16*8);
44         memcpy(ctx->t, tweak, 2*8);
45         uint8_t i;
46         ctx->k[16] = THREEFISH_KEY_CONST;
47         for(i=0; i<8; ++i){
48                 ctx->k[16] ^= K(i);
49         }
50         ctx->t[2] = T(0) ^ T(1);
51 }
52 */
53 /*
54  * param key:   r24:r25
55  * param tweak: r22:r23
56  * param ctx:   r20:r21
57  */
58 .global threefish1024_init
59 threefish1024_init:
60         push_range 14, 17
61         movw r30, r20
62         movw r26, r24
63         ldi r24, 16
64 ;       ldi A7, 0x55
65 ;       mov A6, A7
66 ;       movw A4, A6
67 ;       movw A2, A6
68 ;       movw A0, A6
69         ldi A6, 0x22 ; 0x1BD1.1BDA.A9FC.1A22
70         ldi A7, 0x1A
71         movw A0, A6
72         ldi A2, 0xFC
73         ldi A3, 0xA9
74         ldi A4, 0xDA
75         ldi A5, 0x1B
76         ldi A6, 0xD1
77         ldi A7, 0x1B
78 1:
79         ld r0, X+
80         st Z+, r0
81         eor A0, r0
82         ld r0, X+
83         st Z+, r0
84         eor A1, r0
85         ld r0, X+
86         st Z+, r0
87         eor A2, r0
88         ld r0, X+
89         st Z+, r0
90         eor A3, r0
91         ld r0, X+
92         st Z+, r0
93         eor A4, r0
94         ld r0, X+
95         st Z+, r0
96         eor A5, r0
97         ld r0, X+
98         st Z+, r0
99         eor A6, r0
100         ld r0, X+
101         st Z+, r0
102         eor A7, r0
103         dec r24
104         brne 1b
105         st Z+, A0
106         st Z+, A1
107         st Z+, A2
108         st Z+, A3
109         st Z+, A4
110         st Z+, A5
111         st Z+, A6
112         st Z+, A7
113         /* now the tweak */
114         movw r26, r22
115         tst r27
116         brne 3f
117         tst r26
118         brne 3f
119         ldi r26, 3*8
120 1:
121         st Z+, r1
122         dec r26
123         brne 1b
124         rjmp 9f
125 3:
126         ld A0, X+
127         ld A1, X+
128         ld A2, X+
129         ld A3, X+
130         ld A4, X+
131         ld A5, X+
132         ld A6, X+
133         ld A7, X+
134         st Z+, A0
135         st Z+, A1
136         st Z+, A2
137         st Z+, A3
138         st Z+, A4
139         st Z+, A5
140         st Z+, A6
141         st Z+, A7
142         ld r0, X+
143         eor A0, r0
144         st Z+, r0
145         ld r0, X+
146         eor A1, r0
147         st Z+, r0
148         ld r0, X+
149         eor A2, r0
150         st Z+, r0
151         ld r0, X+
152         eor A3, r0
153         st Z+, r0
154         ld r0, X+
155         eor A4, r0
156         st Z+, r0
157         ld r0, X+
158         eor A5, r0
159         st Z+, r0
160         ld r0, X+
161         eor A6, r0
162         st Z+, r0
163         ld r0, X+
164         eor A7, r0
165         st Z+, r0
166         st Z+, A0
167         st Z+, A1
168         st Z+, A2
169         st Z+, A3
170         st Z+, A4
171         st Z+, A5
172         st Z+, A6
173         st Z+, A7
174 9:
175         pop_range 14, 17
176         ret
177
178 /******************************************************************************/
179 /*
180 #define X(a) (((uint64_t*)data)[(a)])
181 void permute_16(void *data){
182         uint64_t t;
183         t = X(1);
184         X(1) = X(9);
185         X(9) = X(7);
186         X(7) = X(15);
187         X(15) = t;
188         t = X(3);
189         X(3) = X(13);
190         X(13) = X(5);
191         X(5) = X(11);
192         X(11) = t;
193         t = X(4);
194         X(4) = X(6);
195         X(6) = t;
196         t = X(8);
197         X(8) = X(10);
198         X(10) = X(12);
199         X(12) = X(14);
200         X(14) = t;
201 }
202 void add_key_16(void *data, const threefish1024_ctx_t *ctx, uint8_t s){
203         uint8_t i;
204         for(i=0; i<13; ++i){
205                 X(i) += ctx->k[(s+i)%17];
206         }
207         X(13) += ctx->k[(s+13)%17] + ctx->t[s%3];
208         X(14) += ctx->k[(s+14)%17] + ctx->t[(s+1)%3];
209         X(15) += ctx->k[(s+15)%17] + s;
210 }
211 void threefish1024_enc(void *data, const threefish1024_ctx_t *ctx){
212         uint8_t i=0,s=0;
213         uint8_t r0[8] = {55, 25, 33, 34, 28, 17, 58, 47};
214         uint8_t r1[8] = {43, 25,  8, 43,  7,  6,  7, 49};
215         uint8_t r2[8] = {37, 46, 18, 25, 47, 18, 32, 27};
216         uint8_t r3[8] = {40, 13, 57, 60, 48, 25, 45, 58};
217         uint8_t r4[8] = {16, 14, 21, 44, 51, 43, 19, 37};
218         uint8_t r5[8] = {22, 13, 12,  9,  9, 42, 18, 48};
219         uint8_t r6[8] = {38, 52, 32, 59, 35, 40,  2, 53};
220         uint8_t r7[8] = {12, 57, 54, 34, 41, 15, 56, 56};
221         do{
222                 if(i%4==0){
223                         add_key_16(data, ctx, s);
224                         ++s;
225                 }
226                 threefish_mix((uint8_t*)data +  0, r0[i%8]);
227                 threefish_mix((uint8_t*)data + 16, r1[i%8]);
228                 threefish_mix((uint8_t*)data + 32, r2[i%8]);
229                 threefish_mix((uint8_t*)data + 48, r3[i%8]);
230                 threefish_mix((uint8_t*)data + 64, r4[i%8]);
231                 threefish_mix((uint8_t*)data + 80, r5[i%8]);
232                 threefish_mix((uint8_t*)data + 96, r6[i%8]);
233                 threefish_mix((uint8_t*)data +112, r7[i%8]);
234                 permute_16(data);
235                 ++i;
236         }while(i!=80);
237         add_key_16(data, ctx, s);
238 }
239 */
240 I     =  2
241 S     =  3
242 DATA0 =  4
243 DATA1 =  5
244 CTX0  =  6
245 CTX1  =  7
246 IDX0  =  8
247 IDX1  =  9
248 IDX2  = 10
249 IDX3  = 11
250 IDX4  = 12
251 IDX5  = 13
252 IDX6  = 14
253 IDX7  = 15
254
255 /*
256  * param data:  r24:r25
257  * param ctx:   r22:r23
258  */
259 .global threefish1024_enc
260 threefish1024_enc:
261         push r28
262         push r29
263         push_range 2, 17
264         movw DATA0, r24
265         movw CTX0, r22
266         clr I
267         clr S
268 1:
269         mov r30,  I
270         andi r30, 0x03
271         breq 2f
272         rjmp 4f
273 2:
274         ldi r30, lo8(threefish1024_slut17)
275         ldi r31, hi8(threefish1024_slut17)
276         add r30, S
277         adc r31, r1
278         lpm IDX0, Z+
279         lpm IDX1, Z+
280         lpm IDX2, Z+
281         lpm IDX3, Z+
282         lpm IDX4, Z+
283         lpm IDX5, Z+
284         lpm IDX6, Z+
285         lpm IDX7, Z
286         movw r30, CTX0
287         movw r26, DATA0
288         add r30, IDX0
289         adc r31, r1
290         rcall add_z_to_x8
291         movw r30, CTX0
292         add r30, IDX1
293         adc r31, r1
294         rcall add_z_to_x8
295         movw r30, CTX0
296         add r30, IDX2
297         adc r31, r1
298         rcall add_z_to_x8
299         movw r30, CTX0
300         add r30, IDX3
301         adc r31, r1
302         rcall add_z_to_x8
303         movw r30, CTX0
304         add r30, IDX4
305         adc r31, r1
306         rcall add_z_to_x8
307         movw r30, CTX0
308         add r30, IDX5
309         adc r31, r1
310         rcall add_z_to_x8
311         movw r30, CTX0
312         add r30, IDX6
313         adc r31, r1
314         rcall add_z_to_x8
315         movw r30, CTX0
316         add r30, IDX7
317         adc r31, r1
318         rcall add_z_to_x8
319         /* second half */
320         ldi r30, lo8(threefish1024_slut17)
321         ldi r31, hi8(threefish1024_slut17)
322         add r30, S
323         adc r31, r1
324         adiw r30, 8
325         lpm IDX0, Z+
326         lpm IDX1, Z+
327         lpm IDX2, Z+
328         lpm IDX3, Z+
329         lpm IDX4, Z+
330         lpm IDX5, Z+
331         lpm IDX6, Z+
332         lpm IDX7, Z
333         movw r30, CTX0
334         add r30, IDX0
335         adc r31, r1
336         rcall add_z_to_x8
337         movw r30, CTX0
338         add r30, IDX1
339         adc r31, r1
340         rcall add_z_to_x8
341         movw r30, CTX0
342         add r30, IDX2
343         adc r31, r1
344         rcall add_z_to_x8
345         movw r30, CTX0
346         add r30, IDX3
347         adc r31, r1
348         rcall add_z_to_x8
349         movw r30, CTX0
350         add r30, IDX4
351         adc r31, r1
352         rcall add_z_to_x8
353         movw r30, CTX0
354         add r30, IDX5
355         adc r31, r1
356         rcall add_z_to_x8
357         movw r30, CTX0
358         add r30, IDX6
359         adc r31, r1
360         rcall add_z_to_x8
361         movw r30, CTX0
362         add r30, IDX7
363         adc r31, r1
364         rcall add_z_to_x8
365         /* now the remaining key */
366         sbiw r26, 3*8
367         ldi r30, lo8(threefish1024_slut3)
368         ldi r31, hi8(threefish1024_slut3)
369         add r30, S
370         adc r31, r1
371         lpm IDX0, Z+
372         lpm IDX1, Z
373         movw r30, CTX0
374         adiw r30, 7*8 /* make Z pointing to (extended tweak) */
375         adiw r30, 7*8
376         adiw r30, 3*8
377         movw IDX2, r30
378         add r30, IDX0
379         adc r31, r1
380         rcall add_z_to_x8
381         movw r30, IDX2
382         add r30, IDX1
383         adc r31, r1
384         rcall add_z_to_x8
385         ld r0, X
386         add r0, S
387         st X+, r0
388         ld r0, X
389         adc r0, r1
390         st X+, r0
391         ld r0, X
392         adc r0, r1
393         st X+, r0
394         ld r0, X
395         adc r0, r1
396         st X+, r0
397         ld r0, X
398         adc r0, r1
399         st X+, r0
400         ld r0, X
401         adc r0, r1
402         st X+, r0
403         ld r0, X
404         adc r0, r1
405         st X+, r0
406         ld r0, X
407         adc r0, r1
408         st X+, r0
409         inc S
410         mov r26, S
411         cpi r26, 21
412         brmi 4f
413 exit:
414         pop_range 2, 17
415         pop r29
416         pop r28
417         ret
418 4:
419         /* call mix */
420         ldi r30, lo8(threefish1024_rc0)
421         ldi r31, hi8(threefish1024_rc0)
422         mov r26, I
423         andi r26, 0x07
424         add r30, r26
425         adc r31, r1
426         lpm r22, Z
427         adiw r30, 8
428         lpm IDX0, Z
429         adiw r30, 8
430         lpm IDX1, Z
431         adiw r30, 8
432         lpm IDX2, Z
433         adiw r30, 8
434         lpm IDX3, Z
435         adiw r30, 8
436         lpm IDX4, Z
437         adiw r30, 8
438         lpm IDX5, Z
439         adiw r30, 8
440         lpm IDX6, Z
441         push IDX6
442         push IDX5
443         push IDX4
444         push IDX3
445         push IDX2
446
447         movw r24, DATA0
448         call threefish_mix_asm /* no rcall? */
449         movw r24, DATA0
450         adiw r24, 16
451         mov r22, IDX0
452         call threefish_mix_asm /* no rcall? */
453         movw r24, DATA0
454         adiw r24, 32
455         mov r22, IDX1
456         call threefish_mix_asm /* no rcall? */
457         movw r24, DATA0
458         adiw r24, 48
459         pop r22
460         call threefish_mix_asm /* no rcall? */
461         movw r24, DATA0
462         adiw r24, 63
463         adiw r24,  1
464         pop r22
465         call threefish_mix_asm /* no rcall? */
466         movw r24, DATA0
467         adiw r24, 63
468         adiw r24, 17
469         pop r22
470         call threefish_mix_asm /* no rcall? */
471         movw r24, DATA0
472         adiw r24, 63
473         adiw r24, 33
474         pop r22
475         call threefish_mix_asm /* no rcall? */
476         movw r24, DATA0
477         adiw r24, 63
478         adiw r24, 49
479         pop r22
480         call threefish_mix_asm /* no rcall? */
481         /* now the permutation */
482         movw r26, DATA0  /* X1 <-> X15 */
483         adiw r26, 1*8
484         movw r30, DATA0
485         adiw r30, 7*8+4
486         adiw r30, 7*8+4
487         rcall xchg_zx8
488         movw r26, DATA0  /* X1 <-> X9 */
489         adiw r26, 1*8
490         movw r30, DATA0
491         adiw r30, 7*8
492         adiw r30, 2*8
493         rcall xchg_zx8
494         movw r26, DATA0  /* X9 <-> X7 */
495         adiw r26, 7*8
496         adiw r26, 2*8
497         movw r30, DATA0
498         adiw r30, 7*8
499         rcall xchg_zx8
500         /* --- */
501         movw r26, DATA0  /* X3 <-> X11 */
502         adiw r26, 3*8
503         movw r30, DATA0
504         adiw r30, 7*8
505         adiw r30, 4*8
506         rcall xchg_zx8
507         movw r26, DATA0  /* X3 <-> X13 */
508         adiw r26, 3*8
509         movw r30, DATA0
510         adiw r30, 7*8
511         adiw r30, 6*8
512         rcall xchg_zx8
513         movw r26, DATA0  /* X13 <-> X5 */
514         adiw r26, 7*8
515         adiw r26, 6*8
516         movw r30, DATA0
517         adiw r30, 5*8
518         rcall xchg_zx8
519         /* --- */
520         movw r26, DATA0  /* X8 <-> X14 */
521         adiw r26, 7*8
522         adiw r26, 1*8
523         movw r30, DATA0
524         adiw r30, 7*8
525         adiw r30, 7*8
526         rcall xchg_zx8
527         movw r26, DATA0  /* X8 <-> X10 */
528         adiw r26, 7*8
529         adiw r26, 1*8
530         movw r30, DATA0
531         adiw r30, 7*8
532         adiw r30, 3*8
533         rcall xchg_zx8
534         movw r26, DATA0  /* X10 <-> X12 */
535         adiw r26, 7*8
536         adiw r26, 3*8
537         movw r30, DATA0
538         adiw r30, 7*8
539         adiw r30, 5*8
540         rcall xchg_zx8
541         /* --- */
542         movw r26, DATA0  /* X4 <-> X6 */
543         adiw r26, 4*8
544         movw r30, DATA0
545         adiw r30, 6*8
546         rcall xchg_zx8
547
548         inc I
549 ;       mov r26, I
550 ;       cpi r26, 5
551 ;       brne 9f
552 ;       rjmp exit
553 9:
554         rjmp 1b
555
556 threefish1024_slut17:
557         .byte 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38
558         .byte 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78
559         .byte 0x80, 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30
560         .byte 0x38, 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70
561         .byte 0x78, 0x80, 0x00, 0x08, 0x10
562 threefish1024_slut3:
563     .byte 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08
564         .byte 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00
565         .byte 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10
566         .byte 0x00
567 /* old round constants
568 threefish1024_rc0: .byte 0x79, 0x31, 0x41, 0x42, 0x34, 0x21, 0x72, 0x69
569 threefish1024_rc1: .byte 0x53, 0x31, 0x10, 0x53, 0x19, 0x1a, 0x19, 0x61
570 threefish1024_rc2: .byte 0x5b, 0x6a, 0x22, 0x31, 0x69, 0x22, 0x40, 0x33
571 threefish1024_rc3: .byte 0x50, 0x2b, 0x71, 0x74, 0x60, 0x31, 0x6b, 0x72
572 threefish1024_rc4: .byte 0x20, 0x2a, 0x3b, 0x54, 0x63, 0x53, 0x23, 0x5b
573 threefish1024_rc5: .byte 0x3a, 0x2b, 0x14, 0x11, 0x11, 0x52, 0x22, 0x60
574 threefish1024_rc6: .byte 0x5a, 0x64, 0x40, 0x73, 0x43, 0x50, 0x02, 0x7b
575 threefish1024_rc7: .byte 0x14, 0x71, 0x7a, 0x42, 0x51, 0x29, 0x70, 0x70
576 */
577 threefish1024_rc0:  .byte 0x30, 0x5a, 0x41, 0x1b, 0x51, 0x20, 0x49, 0x11
578 threefish1024_rc1:  .byte 0x2b, 0x23, 0x04, 0x24, 0x11, 0x42, 0x54, 0x60
579 threefish1024_rc2:  .byte 0x10, 0x12, 0x63, 0x60, 0x5b, 0x70, 0x69, 0x43
580 threefish1024_rc3:  .byte 0x69, 0x79, 0x2b, 0x51, 0x49, 0x63, 0x6a, 0x64
581 threefish1024_rc4:  .byte 0x10, 0x61, 0x42, 0x69, 0x14, 0x04, 0x23, 0x39
582 threefish1024_rc5:  .byte 0x21, 0x22, 0x51, 0x34, 0x69, 0x7b, 0x52, 0x49
583 threefish1024_rc6:  .byte 0x3a, 0x39, 0x73, 0x20, 0x54, 0x52, 0x54, 0x5b
584 threefish1024_rc7:  .byte 0x5b, 0x64, 0x21, 0x31, 0x4a, 0x51, 0x31, 0x24
585
586 add_z_to_x8:
587         ld r0, Z+
588         ld r1, X
589         add r1, r0
590         st X+, r1
591         ld r0, Z+
592         ld r1, X
593         adc r1, r0
594         st X+, r1
595         ld r0, Z+
596         ld r1, X
597         adc r1, r0
598         st X+, r1
599         ld r0, Z+
600         ld r1, X
601         adc r1, r0
602         st X+, r1
603         ld r0, Z+
604         ld r1, X
605         adc r1, r0
606         st X+, r1
607         ld r0, Z+
608         ld r1, X
609         adc r1, r0
610         st X+, r1
611         ld r0, Z+
612         ld r1, X
613         adc r1, r0
614         st X+, r1
615         ld r0, Z+
616         ld r1, X
617         adc r1, r0
618         st X+, r1
619         clr r1
620         ret
621
622 T0 = IDX0
623 T1 = 0
624 CNT = 24
625 xchg_zx8:
626         ldi CNT, 8
627 1:      ld T0, X
628         ld T1, Z
629         st X+, T1
630         st Z+, T0
631         dec CNT
632         brne 1b
633         ret
634
635
636