]> git.cryptolib.org Git - avr-crypto-lib.git/blob - shabal/shabal-asm.S
9d9827e47294236a767fe2a9a6bfff34d741eb3a
[avr-crypto-lib.git] / shabal / shabal-asm.S
1 /* shabal-asm.S */
2 /*
3     This file is part of the AVR-Crypto-Lib.
4     Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
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    shabal-asm.S
21  * \author  Daniel Otte
22  * \email   bg@nerilex.org
23  * \date    2009-04-27
24  * \license GPLv3 or later
25  */ 
26
27 #include "avr-asm-macros.S"
28
29 /******************************************************************************/
30 /*
31 void shabal_p(shabal_ctx_t *ctx, const void *m){
32         uint8_t i,j;
33         for(i=0;i<16;++i){
34                 ctx->b[i] = ROTL32(ctx->b[i],17);
35         }
36         for(j=0;j<SHABAL_P;++j){
37                 for(i=0;i<16;++i){
38                         ctx->a[(i+16*j)%SHABAL_R] =
39                                 shabal_u(ctx->a[(i+16*j)%SHABAL_R] 
40                                         ^ shabal_v(ROTL32(ctx->a[(i+16*j+SHABAL_R-1)%SHABAL_R],15))
41                                     ^ ctx->c[(8-i+16)%16])
42                                 ^ ctx->b[(i+SHABAL_O1)%16]
43                                 ^ ((ctx->b[(i+SHABAL_O2)%16]) & ~(ctx->b[(i+SHABAL_O3)%16]))
44                                 ^ ((uint32_t*)m)[i];
45                         ctx->b[i] = ROTL32(ctx->b[i], 1) ^ ~(ctx->a[(i+16*j)%SHABAL_R]);
46                 }
47         }
48         
49         for(j=0;j<36;++j){
50                 ctx->a[j%SHABAL_R] += ctx->c[(j+3)%16];
51         }
52 }
53 */
54 MB0 =  2
55 MB1 =  3
56 AB0 =  4
57 AB1 =  5
58 BB0 =  6
59 BB1 =  7
60 CB0 =  8
61 CB1 =  9
62 AL0 = 10
63 AL1 = 11
64 AL2 = 12
65 AL3 = 13
66 A0  = 14
67 A1  = 15
68 A2  = 16
69 A3  = 17
70 B0  = 18
71 B1  = 19
72 B2  = 20
73 B3  = 21
74 I   = 22
75 J   = 23
76 T0  = 26
77 T1  = 27
78 T2  = 28
79 T3  = 29
80 /*
81  * param ctx: r24:r25
82  * param m:   r22:r23 
83  */
84 ; .global shabal_p
85 shabal_p:
86         push_range 2, 17
87         push r28
88         push r29
89         movw MB0, r22
90         movw r30, r24
91         adiw r30, 8
92         ld BB0, Z+
93         ld BB1, Z+
94         ld CB0, Z+
95         ld CB1, Z+
96         movw AB0, r30
97         movw r30, BB0
98         adiw r30, 16*4-1
99         adiw r30, 1
100         ldi r24, 16
101 1:
102         ld A3, -Z
103         ld A2, -Z
104         ld A1, -Z
105         ld A0, -Z       
106         mov r0, A3
107         rol r0
108         rol A0
109         rol A1
110         rol A2
111         rol A3
112         std Z+0, A2
113         std Z+1, A3
114         std Z+2, A0
115         std Z+3, A1
116         dec r24
117         brne 1b
118         movw B0, A2
119         movw B2, A0
120         /* load ctx->a[(i+16*j-1)%12]*/
121         movw r26, AB0
122         adiw r26, 4*11
123         ld AL0, X+
124         ld AL1, X+
125         ld AL2, X+
126         ld AL3, X+
127         clr I
128         clr J
129 1:
130         /* ROTL32(AL, 15)*/
131         movw T0, AL2
132         movw T2, AL0
133         mov r0, T0
134         ror r0
135         ror T3
136         ror T2
137         ror T1
138         ror T0
139         movw AL0, T0
140         movw AL2, T2
141         /* apply V to AL */
142         movw A0, AL0
143         movw A2, AL2
144         lsl A0
145         rol A1
146         rol A2
147         rol A3
148         lsl A0
149         rol A1
150         rol A2
151         rol A3
152         add A0, AL0
153         adc A1, AL1     
154         adc A2, AL2
155         adc A3, AL3
156         /* xor in ctx->c[(8-i+16)%16] */
157         ldi T0, 24
158         sub T0, I
159         andi T0, 0x0f
160         lsl T0
161         lsl T0
162         movw r30, CB0
163         add r30, T0
164         adc r31, r1
165         ld r0, Z+
166         eor A0, r0
167         ld r0, Z+
168         eor A1, r0
169         ld r0, Z+
170         eor A2, r0
171         ld r0, Z+
172         eor A3, r0
173         /* xor in ctx->a[(i+16*j)%12] */
174         mov T0, J
175         swap T0 /* *=16 */
176         add T0, I
177         ldi r30, lo8(mod12table)
178         ldi r31, hi8(mod12table)
179         add r30, T0
180         adc r31, r1
181         lpm T0, Z
182         movw r30, AB0
183         add r30, T0
184         adc r31, r1
185         movw T2, r30
186         ld r0, Z+
187         eor A0, r0
188         ld r0, Z+
189         eor A1, r0
190         ld r0, Z+
191         eor A2, r0
192         ld r0, Z+
193         eor A3, r0
194         /* AL = 3*A */
195         movw AL0, A0
196         movw AL2, A2
197         lsl AL0
198         rol AL1
199         rol AL2
200         rol AL3
201         add AL0, A0
202         adc AL1, A1
203         adc AL2, A2
204         adc AL3, A3
205         /* xor in ctx->b[(i+13)%16] */
206         ldi T0, 13
207         add T0, I
208         andi T0, 0x0f
209         lsl T0
210         lsl T0
211         movw r30, BB0
212         add r30, T0
213         adc r31, r1
214         ld r0, Z+
215         eor AL0, r0
216         ld r0, Z+
217         eor AL1, r0
218         ld r0, Z+
219         eor AL2, r0
220         ld r0, Z+
221         eor AL3, r0
222         /* load ctx->b[(i+9)%16] into A */
223         ldi T0, 9
224         add T0, I
225         andi T0, 0x0f
226         lsl T0
227         lsl T0
228         movw r30, BB0
229         add r30, T0
230         adc r31, r1
231         ld A0, Z+
232         ld A1, Z+
233         ld A2, Z+
234         ld A3, Z+
235         /* and in ~(ctx->b[(i+6)%16]) */
236         ldi T0, 6
237         add T0, I
238         andi T0, 0x0f
239         lsl T0
240         lsl T0
241         movw r30, BB0
242         add r30, T0
243         adc r31, r1
244         ld r0, Z+
245         com r0
246         and A0, r0
247         ld r0, Z+
248         com r0
249         and A1, r0
250         ld r0, Z+
251         com r0
252         and A2, r0
253         ld r0, Z+
254         com r0
255         and A3, r0
256         /* xor A into AL */
257         eor AL0, A0
258         eor AL1, A1
259         eor AL2, A2
260         eor AL3, A3
261         /* xor m[i] into AL */
262         mov T0, I
263         lsl T0
264         lsl T0
265         movw r30, MB0
266         add r30, T0
267         adc r31, r1
268         ld r0, Z+
269         eor AL0, r0
270         ld r0, Z+
271         eor AL1, r0
272         ld r0, Z+
273         eor AL2, r0
274         ld r0, Z+
275         eor AL3, r0
276         /* A (AL) is done, now store it */
277         movw r30, T2
278         st Z+, AL0
279         st Z+, AL1
280         st Z+, AL2
281         st Z+, AL3
282         /* process ctx->b[i] */
283         /* ROTL32(b, 1)*/
284         mov r0, B3
285         rol r0
286         rol B0
287         rol B1
288         rol B2
289         rol B3
290         /* xor in ~(ctx->a[(i+16*j)%SHABAL_R]) */
291         movw A0, AL0
292         movw A2, AL2
293         com A0
294         com A1
295         com A2
296         com A3
297         eor B0, A0
298         eor B1, A1
299         eor B2, A2
300         eor B3, A3
301         /* store B */
302         movw r30, BB0
303         mov T0, I
304         lsl T0
305         lsl T0
306         add r30, T0
307         adc r31, r1
308         st Z+, B0
309         st Z+, B1
310         st Z+, B2
311         st Z+, B3
312         inc I
313         cpi I, 16
314         brne local_reload
315         inc J
316         cpi J, 3
317         brne global_reload
318         rjmp addition
319 global_reload:
320         clr I
321 local_reload:   
322         mov T0, I
323         lsl T0
324         lsl T0
325         movw r30, BB0 
326         add r30, T0
327         adc r31, r1
328         ld B0, Z+
329         ld B1, Z+
330         ld B2, Z+
331         ld B3, Z+
332         
333         rjmp 1b
334 addition:
335         clr J
336         movw r30, AB0
337         movw r26, CB0
338         adiw r26, 3*4
339 1:
340         /* J = 0..11 */
341         ld AL0, X+
342         ld A0, Z
343         add A0, AL0
344         st Z+, A0
345         ld AL0, X+
346         ld A0, Z
347         adc A0, AL0
348         st Z+, A0
349         ld AL0, X+
350         ld A0, Z
351         adc A0, AL0
352         st Z+, A0
353         ld AL0, X+
354         ld A0, Z
355         adc A0, AL0
356         st Z+, A0
357         inc J
358         cpi J, 12
359         brne 1b
360         /* J = 12 */
361         movw r30, AB0
362         ld AL0, X+
363         ld A0, Z
364         add A0, AL0
365         st Z+, A0
366         ld AL0, X+
367         ld A0, Z
368         adc A0, AL0
369         st Z+, A0
370         ld AL0, X+
371         ld A0, Z
372         adc A0, AL0
373         st Z+, A0
374         ld AL0, X+
375         ld A0, Z
376         adc A0, AL0
377         st Z+, A0
378         inc J
379         /* J= 13..23*/
380         movw r26, CB0
381 1:      
382         ld AL0, X+
383         ld A0, Z
384         add A0, AL0
385         st Z+, A0
386         ld AL0, X+
387         ld A0, Z
388         adc A0, AL0
389         st Z+, A0
390         ld AL0, X+
391         ld A0, Z
392         adc A0, AL0
393         st Z+, A0
394         ld AL0, X+
395         ld A0, Z
396         adc A0, AL0
397         st Z+, A0
398         inc J
399         cpi J, 24
400         brne 1b
401         /* J= 24..28*/
402         movw r30, AB0
403 1:      
404         ld AL0, X+
405         ld A0, Z
406         add A0, AL0
407         st Z+, A0
408         ld AL0, X+
409         ld A0, Z
410         adc A0, AL0
411         st Z+, A0
412         ld AL0, X+
413         ld A0, Z
414         adc A0, AL0
415         st Z+, A0
416         ld AL0, X+
417         ld A0, Z
418         adc A0, AL0
419         st Z+, A0
420         inc J
421         cpi J, 29
422         brne 1b
423
424         /* J= 29..35*/
425         movw r26, CB0
426 1:      
427         ld AL0, X+
428         ld A0, Z
429         add A0, AL0
430         st Z+, A0
431         ld AL0, X+
432         ld A0, Z
433         adc A0, AL0
434         st Z+, A0
435         ld AL0, X+
436         ld A0, Z
437         adc A0, AL0
438         st Z+, A0
439         ld AL0, X+
440         ld A0, Z
441         adc A0, AL0
442         st Z+, A0
443         inc J
444         cpi J, 36
445         brne 1b 
446 exit:   
447         pop r29
448         pop r28
449         pop_range 2, 17
450         ret
451
452 mod12table:
453         .byte  0,  4,  8, 12, 16, 20, 24, 28
454         .byte 32, 36, 40, 44,  0,  4,  8, 12
455         .byte 16, 20, 24, 28, 32, 36, 40, 44
456         .byte  0,  4,  8, 12, 16, 20, 24, 28
457         .byte 32, 36, 40, 44,  0,  4,  8, 12
458         .byte 16, 20, 24, 28, 32, 36, 40, 44
459         
460 /******************************************************************************/
461 /*
462 void shabal_nextBlock(shabal_ctx_t *ctx, const void *block){
463         uint8_t i;
464         uint32_t *t;
465         for(i=0;i<16;++i){
466                 ctx->b[i] += ((uint32_t*)block)[i];
467         }
468         ctx->a[0] ^= ctx->w.w32[0];
469         ctx->a[1] ^= ctx->w.w32[1];
470         shabal_p(ctx, block);
471         for(i=0;i<16;++i){
472                 ctx->c[i] -= ((uint32_t*)block)[i];
473         }
474         ctx->w.w64++;
475         t = ctx->c;
476         ctx->c = ctx->b;
477         ctx->b = t;
478 }
479 */
480 /*
481  * param ctx:    r24:r25
482  * param block:  r22:r23
483  */
484 MB0  = 14
485 MB1  = 15
486 CTX0 = 16
487 CTX1 = 17
488 .global shabal_nextBlock
489 shabal_nextBlock:
490         push_range 14, 17
491         movw CTX0, r24
492         movw MB0, r22
493         /* xor W into A and increment W */
494         movw r30, CTX0
495         ldi r19, 8
496         sec
497 1:      
498         ld r20, Z
499         ldd r21, Z+(8+4)
500         eor r21, r20
501         std Z+(8+4), r21
502         adc r20, r1
503         st Z+, r20 
504         dec r19
505         brne 1b
506         /* add block to ctx->b */
507         ld r26, Z+
508         ld r27, Z
509         movw r30, MB0
510         ldi r19, 16
511 1:      
512         ld r0, X
513         ld r18, Z+
514         add r0, r18
515         st X+, r0
516         ld r0, X
517         ld r18, Z+
518         adc r0, r18
519         st X+, r0
520         ld r0, X
521         ld r18, Z+
522         adc r0, r18
523         st X+, r0
524         ld r0, X
525         ld r18, Z+
526         adc r0, r18
527         st X+, r0
528         dec r19
529         brne 1b
530         /* call shbal_p */
531         rcall shabal_p
532         /* sub block from ctx->c */
533         movw r30, CTX0
534         adiw r30, 8+2
535         ld r26, Z+
536         ld r27, Z
537         movw r30, MB0
538         ldi r19, 16
539 1:      
540         ld r0, X
541         ld r18, Z+
542         sub r0, r18
543         st X+, r0
544         ld r0, X
545         ld r18, Z+
546         sbc r0, r18
547         st X+, r0
548         ld r0, X
549         ld r18, Z+
550         sbc r0, r18
551         st X+, r0
552         ld r0, X
553         ld r18, Z+
554         sbc r0, r18
555         st X+, r0
556         dec r19
557         brne 1b
558         /* xchange ctx->b with ctx->c*/
559         movw r30, CTX0
560         ldd r22, Z+8
561         ldd r23, Z+9
562         ldd r24, Z+10
563         ldd r25, Z+11
564         std Z+10, r22
565         std Z+11, r23
566         std Z+8,  r24
567         std Z+9,  r25
568         pop_range 14, 17
569         ret
570
571 /******************************************************************************/
572 /*
573 void shabal_lastBlock(shabal_ctx_t *ctx, const void *block, uint16_t length_b){
574         uint8_t i,j;
575         uint32_t *t;
576         uint8_t buffer[64];
577         while(length_b>=SHABAL_BLOCKSIZE){
578                 shabal_nextBlock(ctx, block);
579                 block = (uint8_t*)block + SHABAL_BLOCKSIZE_B;
580                 length_b -= SHABAL_BLOCKSIZE;
581         }
582         memset(buffer, 0, 64);
583         memcpy(buffer, block, (length_b+7)/8);
584         buffer[length_b/8] |= 0x80>>(length_b%8);
585         for(i=0;i<16;++i){
586                 ctx->b[i] += ((uint32_t*)buffer)[i];
587         }
588         for(j=0; j<4;++j){
589                 ctx->a[0] ^= ctx->w.w32[0];
590                 ctx->a[1] ^= ctx->w.w32[1];
591                 shabal_p(ctx, buffer);
592                 t = ctx->c;
593                 ctx->c = ctx->b;
594                 ctx->b = t;
595         }        
596 }
597 */
598 I    = 16
599 LEN0 = 16
600 LEN1 = 17
601 CTX0 = 14
602 CTX1 = 15
603 MB0  = 12
604 MB1  = 13
605 /*
606  * param ctx:       r24:r25
607  * param block:     r22:r23
608  * param length_b:  r20:r21
609  */
610 .global shabal_lastBlock
611 shabal_lastBlock:
612         push_range 12, 17
613         movw CTX0, r24
614         movw MB0,  r22
615         movw LEN0, r20
616 1:
617         cpi LEN1, 0x02
618         brlo 2f
619         movw r24, CTX0
620         movw r22, MB0
621         rcall shabal_nextBlock
622         subi LEN1, 0x02
623         ldi r18, 64
624         add     MB0, r18
625         adc MB1, r1
626         rjmp 1b
627 2:      
628         stack_alloc_large 64
629         adiw r30, 1 /* Z points at buffer */
630         movw r26, MB0
631         /* r24 = LEN/8*/
632         movw r24, LEN0
633         lsr r25
634         ror r24
635         lsr r24
636         lsr r24
637         ldi r25, 64-1
638         sub r25, r24
639         tst r24
640         breq 32f
641 31:
642         ld r0, X+
643         st Z+, r0
644         dec r24
645         brne 31b
646 32:
647         ldi r18, 0x80
648         andi LEN0, 0x07
649         breq append_0x80
650         ld r0, X+
651 33:
652         lsr r18
653         dec LEN0
654         brne 33b
655         or r0, r18
656         st Z+, r0
657         rjmp append_zeros
658 append_0x80:
659         st Z+, r18
660 append_zeros:
661         tst r25
662         breq 4f
663 34: st Z+, r1
664         dec r25
665         brne 34b
666 4:              
667         sbiw r30, 63
668         sbiw r30,  1
669         movw MB0, r30
670         movw r26, CTX0
671         adiw r26, 8
672         ld r24, X+
673         ld r25, X
674         movw r26, r24
675         ldi r18, 16
676 41: 
677         ld r24, X
678         ld r25, Z+
679         add r24, r25
680         st X+, r24
681         ld r24, X
682         ld r25, Z+
683         adc r24, r25
684         st X+, r24      
685         ld r24, X
686         ld r25, Z+
687         adc r24, r25
688         st X+, r24      
689         ld r24, X
690         ld r25, Z+
691         adc r24, r25
692         st X+, r24      
693         dec r18
694         brne 41b
695         /* final loop */
696         ldi I, 4
697 5:
698         /* xor W into A */
699         movw r30, CTX0
700         ldi r19, 8
701 51:     
702         ld  r24, Z+
703         ldd r25, Z+(8+4-1)
704         eor r24, r25
705         std Z+(8+4-1), r24      
706         dec r19
707         brne 51b
708         movw r24, CTX0
709         movw r22, MB0
710         rcall shabal_p
711         movw r30, CTX0
712         ldd r22, Z+8
713         ldd r23, Z+9
714         ldd r24, Z+10
715         ldd r25, Z+11
716         std Z+10, r22
717         std Z+11, r23
718         std Z+8,  r24
719         std Z+9,  r25
720         dec I
721         brne 5b
722         
723         stack_free_large 64
724         pop_range 12, 17
725         ret
726
727         
728
729         
730         
731         
732         
733         
734         
735         
736         
737         
738         
739