]> git.cryptolib.org Git - avr-crypto-lib.git/blob - bmw/bmw_small-asm.S
some improvments for BMW
[avr-crypto-lib.git] / bmw / bmw_small-asm.S
1 /* bmw_small-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 /*
21  * File:        bmw_small-asm.S
22  * Author:      Daniel Otte
23  * Date:        2009-11-13
24  * License:     GPLv3 or later
25  * Description: implementation of BlueMidnightWish
26  *
27  */
28
29 #include "avr-asm-macros.S"
30
31 shiftcodetable:
32         .byte 0x00 ;  0
33         .byte 0x01 ;  1
34         .byte 0x02 ;  2
35         .byte 0x03 ;  3
36         .byte 0x04 ;  4
37         .byte 0x1B ;  5
38         .byte 0x1A ;  6
39         .byte 0x19 ;  7
40         .byte 0x10 ;  8
41 shiftcodetable_9:
42         .byte 0x11 ;  9
43         .byte 0x12 ; 10
44         .byte 0x13 ; 11
45         .byte 0x2C ; 12
46         .byte 0x2B ; 13
47         .byte 0x2A ; 14
48         .byte 0x29 ; 15
49         .byte 0x20 ; 16
50         .byte 0x21 ; 17 unused but necesseray for padding
51
52
53
54 /*******************************************************************************
55  * shiftl32
56  *   value: r25:r22
57  *   shift: r20
58  */
59 shiftl32:
60 1:
61 ;       clc
62         lsl r22
63         rol r23
64         rol r24
65         rol r25
66         dec r20
67         brne 1b
68         ret
69
70 /*******************************************************************************
71  * shiftr32
72  *   value: r25:r22
73  *   shift: r20
74  */
75 shiftr32:
76 1:
77 ;       clc
78         lsr r25
79         ror r24
80         ror r23
81         ror r22
82         dec r20
83         brne 1b
84         ret
85
86 /*******************************************************************************
87  * rotl32
88  *   value: r25:r22
89  *   shift: r20
90  */
91 rotl32:
92         mov r21, r25
93 1:
94         lsl r21
95         rol r22
96         rol r23
97         rol r24
98         rol r25
99         dec r20
100         brne 1b
101         ret
102
103 /*******************************************************************************
104  * rotr32
105  *   value: r25:r22
106  *   shift: r20
107  */
108 rotr32:
109         mov r21, r22
110 1:
111         lsr r21
112         ror r25
113         ror r24
114         ror r23
115         ror r22
116         dec r20
117         brne 1b
118 some_ret:
119         ret
120
121 /*******************************************************************************
122  * rotl32p9
123  *   value: r25:r22
124  *   shift: r20
125  */
126 rotl32p9:
127         push_range 30, 31
128         ldi r30, lo8(shiftcodetable_9)
129         ldi r31, hi8(shiftcodetable_9)
130         add r30, r20
131         adc r31, r1
132         lpm r20, Z
133         pop_range 30, 31
134         sbrs r20, 4
135         rjmp 2f
136         mov r0, r25
137         mov r25, r24
138         mov r24, r23
139         mov r23, r22
140         mov r22, r0
141 2:      sbrs r20, 5
142         rjmp 3f
143         movw r0, r24
144         movw r24, r22
145         movw r22, r0
146         clr r1
147 3:  bst r20, 3
148         andi r20, 0x07
149         breq some_ret
150         brts rotr32
151         rjmp rotl32
152
153
154 /*******************************************************************************
155 * uint32_t rotl_addel(uint32_t x, uint8_t v){
156 *       uint32_t r;
157 *       r =  ROTL32(x, (v&0xf)+1);
158 *       return r;
159 * }
160 * param x: r25:r22
161 * param v: r20
162 */
163 .global rotl_addel
164 rotl_addel:
165         andi r20, 0x0f
166         inc r20
167         ldi r30, lo8(shiftcodetable)
168         ldi r31, hi8(shiftcodetable)
169         add r30, r20
170         adc r31, r1
171         lpm r20, Z
172         sbrs r20, 4
173         rjmp 1f
174         mov r21, r25
175         mov r25, r24
176         mov r24, r23
177         mov r23, r22
178         mov r22, r21
179 1:  sbrs r20, 5
180         rjmp 2f
181         movw r30, r24
182         movw r24, r22
183         movw r22, r30
184 2:  bst  r20, 3
185         andi r20, 0x07
186         brne 3f
187         ret
188 3:
189         brts rotr32; 4f
190         rjmp rotl32
191 ;4:     rjmp rotr32
192
193 /******************************************************************************/
194
195 preg0 = 22 /* preg for processing register */
196 preg1 = 23
197 preg2 = 24
198 preg3 = 25
199 breg0 = 26 /* breg for backup register */
200 breg1 = 27
201 breg2 = 18
202 breg3 = 19
203 areg0 =  0 /* areg for accumulator register */
204 areg1 =  1
205 areg2 = 30
206 areg3 = 31
207
208 /*******************************************************************************
209 * uint32_t bmw_small_s0(uint32_t x){
210 *       uint32_t r;
211 *       r =   SHR32(x, 1)
212 *               ^ SHL32(x, 3)
213 *               ^ ROTL32(x, 4)
214 *               ^ ROTR32(x, 13);
215 *       return r;
216 * }
217 */
218 .global bmw_small_s0
219 bmw_small_s0:
220         movw breg0, preg0
221         movw breg2, preg2
222         ldi r20, 1
223         rcall shiftr32
224         movw areg2, preg2
225         movw areg0, preg0
226         movw preg2, breg2
227         movw preg0, breg0
228         ldi r20, 3
229         rcall shiftl32
230         eor areg0, preg0
231         eor areg1, preg1
232         eor areg2, preg2
233         eor areg3, preg3
234         movw preg2, breg2
235         movw preg0, breg0
236         ldi r20, 4
237         rcall rotl32
238         eor areg0, preg0
239         eor areg1, preg1
240         eor areg2, preg2
241         eor areg3, preg3
242         /* now the trick, we simply can rotate the old value to the right by 17 */
243         movw breg0, preg0 /* first rotate by 16 */
244         movw preg0, preg2
245         movw preg2, breg0
246 outro_1:
247         ldi r20, 1
248         rcall rotr32
249 outro_2:
250         eor preg0, areg0
251         eor preg1, areg1
252         eor preg2, areg2
253         eor preg3, areg3
254         clr r1
255         ret
256
257 /*******************************************************************************
258 * uint32_t bmw_small_s1(uint32_t x){
259 *       uint32_t r;
260 *       r =   SHR32(x, 1)
261 *               ^ SHL32(x, 2)
262 *               ^ ROTL32(x, 8)
263 *               ^ ROTR32(x, 9);
264 *       return r;
265 * }
266 */
267 .global bmw_small_s1
268 bmw_small_s1:
269         movw breg0, preg0
270         movw breg2, preg2
271         ldi r20, 1
272         rcall shiftr32
273         movw areg2, preg2
274         movw areg0, preg0
275         movw preg2, breg2
276         movw preg0, breg0
277         ldi r20, 2
278         rcall shiftl32
279         eor areg0, preg0
280         eor areg1, preg1
281         eor areg2, preg2
282         eor areg3, preg3
283         eor areg0, breg3
284         eor areg1, breg0
285         eor areg2, breg1
286         eor areg3, breg2
287         mov preg0, breg1
288         mov preg1, breg2
289         mov preg2, breg3
290         mov preg3, breg0
291         rjmp outro_1
292
293 /*******************************************************************************
294 * uint32_t bmw_small_s2(uint32_t x){
295 *       uint32_t r;
296 *       r =   SHR32(x, 2)
297 *               ^ SHL32(x, 1)
298 *               ^ ROTL32(x, 12)
299 *               ^ ROTR32(x, 7);
300 *       return r;
301 * }
302 */
303 .global bmw_small_s2
304 bmw_small_s2:
305         movw breg0, preg0
306         movw breg2, preg2
307         ldi r20, 2
308         rcall shiftr32
309         movw areg2, preg2
310         movw areg0, preg0
311         movw preg2, breg2
312         movw preg0, breg0
313         ldi r20, 1
314         rcall shiftl32
315         eor areg0, preg0
316         eor areg1, preg1
317         eor areg2, preg2
318         eor areg3, preg3
319         movw preg0, breg2
320         movw preg2, breg0
321         ldi r20, 4
322         rcall rotr32
323         eor areg0, preg0
324         eor areg1, preg1
325         eor areg2, preg2
326         eor areg3, preg3
327         mov preg0, breg1
328         mov preg1, breg2
329         mov preg2, breg3
330         mov preg3, breg0
331         ldi r20, 1
332         rcall rotl32
333         rjmp outro_2
334
335 /*******************************************************************************
336 * uint32_t bmw_small_s3(uint32_t x){
337 *       uint32_t r;
338 *       r =   SHR32(x, 2)
339 *               ^ SHL32(x, 2)
340 *               ^ ROTL32(x, 15)
341 *               ^ ROTR32(x, 3);
342 *       return r;
343 * }
344 */
345 .global bmw_small_s3
346 bmw_small_s3:
347         movw breg0, preg0
348         movw breg2, preg2
349         ldi r20, 2
350         rcall shiftr32
351         movw areg2, preg2
352         movw areg0, preg0
353         movw preg2, breg2
354         movw preg0, breg0
355         ldi r20, 2
356         rcall shiftl32
357         eor areg0, preg0
358         eor areg1, preg1
359         eor areg2, preg2
360         eor areg3, preg3
361         movw preg0, breg2
362         movw preg2, breg0
363         ldi r20, 1
364         rcall rotr32
365         eor areg0, preg0
366         eor areg1, preg1
367         eor areg2, preg2
368         eor areg3, preg3
369         movw preg0, breg0
370         movw preg2, breg2
371         ldi r20, 3
372         rcall rotr32
373         rjmp outro_2
374
375 /*******************************************************************************
376 * uint32_t bmw_small_s4(uint32_t x){
377 *       uint32_t r;
378 *       r =  SHR32(x, 1)
379 *                ^ x;
380 *       return r;
381 * }
382 */
383 .global bmw_small_s4
384 bmw_small_s4:
385         movw areg0, preg0
386         movw areg2, preg2
387         ldi r20, 1
388         rcall shiftr32
389         rjmp outro_2
390
391 /*******************************************************************************
392 * uint32_t bmw_small_s5(uint32_t x){
393 *       uint32_t r;
394 *       r =  SHR32(x, 2)
395 *                ^ x;
396 *       return r;
397 * }
398 */
399 .global bmw_small_s5
400 bmw_small_s5:
401         movw areg0, preg0
402         movw areg2, preg2
403         ldi r20, 2
404         rcall shiftr32
405         rjmp outro_2
406
407 /*******************************************************************************
408 * uint32_t bmw_small_r1(uint32_t x){
409 *       uint32_t r;
410 *       r =  ROTL32(x, 3);
411 *       return r;
412 * }
413 */
414 .global bmw_small_r1
415 bmw_small_r1:
416         ldi r20, 3
417         rjmp rotl32
418
419 /*******************************************************************************
420 * uint32_t bmw_small_r2(uint32_t x){
421 *       uint32_t r;
422 *       r =  ROTL32(x, 7);
423 *       return r;
424 * }
425 */
426 .global bmw_small_r2
427 bmw_small_r2:
428         ldi r20, 7
429         rjmp rotl32
430
431 /*******************************************************************************
432 * uint32_t bmw_small_r3(uint32_t x){
433 *       uint32_t r;
434 *       r =  ROTL32(x, 13);
435 *       return r;
436 * }
437 */
438 .global bmw_small_r3
439 bmw_small_r3:
440         movw r18, r24
441         movw r24, r22
442         movw r22, r18
443         ldi r20, 3
444         rjmp rotr32
445
446
447 /*******************************************************************************
448 * uint32_t bmw_small_r4(uint32_t x){
449 *       uint32_t r;
450 *       r =  ROTL32(x, 16);
451 *       return r;
452 * }
453 */
454 .global bmw_small_r4
455 bmw_small_r4:
456         movw r18, r24
457         movw r24, r22
458         movw r22, r18
459         ret
460
461 /*******************************************************************************
462 * uint32_t bmw_small_r5(uint32_t x){
463 *       uint32_t r;
464 *       r =  ROTR32(x, 13);
465 *       return r;
466 * }
467 */
468 .global bmw_small_r5
469 bmw_small_r5:
470         movw r18, r24
471         movw r24, r22
472         movw r22, r18
473         ldi r20, 3
474         rjmp rotl32
475
476 /*******************************************************************************
477 * uint32_t bmw_small_r6(uint32_t x){
478 *       uint32_t r;
479 *       r =  ROTR32(x, 9);
480 *       return r;
481 * }
482 */
483 .global bmw_small_r6
484 bmw_small_r6:
485         mov r18, r22
486         mov r22, r23
487         mov r23, r24
488         mov r24, r25
489         mov r25, r18
490         ldi r20, 1
491         rjmp rotr32
492
493 /*******************************************************************************
494 * uint32_t bmw_small_r7(uint32_t x){
495 *       uint32_t r;
496 *       r =  ROTR32(x, 5);
497 *       return r;
498 * }
499 */
500 .global bmw_small_r7
501 bmw_small_r7:
502         ldi r20, 5
503         rjmp rotr32
504
505 /******************************************************************************/
506
507 const_lut:
508         .long 0x55555550, 0x5aaaaaa5, 0x5ffffffa, 0x6555554f
509         .long 0x6aaaaaa4, 0x6ffffff9, 0x7555554e, 0x7aaaaaa3
510         .long 0x7ffffff8, 0x8555554d, 0x8aaaaaa2, 0x8ffffff7
511         .long 0x9555554c, 0x9aaaaaa1, 0x9ffffff6, 0xa555554b
512
513 /*******************************************************************************
514 * uint32_t addelment(uint8_t j, const uint32_t* m, const uint32_t* h){
515 *       uint32_t r;
516 *       r  = pgm_read_dword(k_lut+j);
517 *       r += rotl_addel(((uint32_t*)m)[j&0xf], j+0);
518 *       r += rotl_addel(((uint32_t*)m)[(j+3)&0xf], j+3);
519 *       r -= rotl_addel(((uint32_t*)m)[(j+10)&0xf], j+10);
520 *       r ^= ((uint32_t*)h)[(j+7)&0xf];
521 *       return r;
522 * }
523 * param j: r24
524 * param m: r22:r23
525 * param h: r20:r21
526 */
527 j    = 16
528 acc2 =  8
529 acc3 =  9
530 h0   = 10
531 h1   = 11
532 m0   = 12
533 m1   = 13
534 acc0 = 14
535 acc1 = 15
536 .global addelement
537 addelement:
538         push_range 8, 16
539         mov j, r24
540         movw h0, r20
541         movw m0, r22
542         mov r25, r24
543         lsl r25
544         lsl r25
545         ldi r30, lo8(const_lut)
546         ldi r31, hi8(const_lut)
547         add r30, r25
548         adc r31, r1
549         lpm acc0, Z+
550         lpm acc1, Z+
551         lpm acc2, Z+
552         lpm acc3, Z+
553
554         mov r20, j
555         andi r20, 0x0f
556         lsl r20
557         lsl r20
558         movw r26, m0
559         add r26, r20
560         adc r27, r1
561         ld r22, X+
562         ld r23, X+
563         ld r24, X+
564         ld r25, X+
565         mov r20, j
566         rcall rotl_addel
567         add acc0, r22
568         adc acc1, r23
569         adc acc2, r24
570         adc acc3, r25
571
572         subi j, -3
573         mov r20, j
574         andi r20, 0x0f
575         lsl r20
576         lsl r20
577         movw r26, m0
578         add r26, r20
579         adc r27, r1
580         ld r22, X+
581         ld r23, X+
582         ld r24, X+
583         ld r25, X+
584         mov r20, j
585         rcall rotl_addel
586         add acc0, r22
587         adc acc1, r23
588         adc acc2, r24
589         adc acc3, r25
590
591         subi j, -7
592         mov r20, j
593         andi r20, 0x0f
594         lsl r20
595         lsl r20
596         movw r26, m0
597         add r26, r20
598         adc r27, r1
599         ld r22, X+
600         ld r23, X+
601         ld r24, X+
602         ld r25, X+
603         mov r20, j
604         rcall rotl_addel
605         sub acc0, r22
606         sbc acc1, r23
607         sbc acc2, r24
608         sbc acc3, r25
609
610         subi j, 3
611         mov r20, j
612         andi r20, 0x0f
613         lsl r20
614         lsl r20
615         movw r26, h0
616         add r26, r20
617         adc r27, r1
618         ld r22, X+
619         ld r23, X+
620         ld r24, X+
621         ld r25, X+
622         eor r22, acc0
623         eor r23, acc1
624         eor r24, acc2
625         eor r25, acc3
626         pop_range 8, 16
627         ret
628
629 /*******************************************************************************
630 * uint32_t bmw_small_expand1(uint8_t j, const void* m, const void* h, const uint32_t* q){
631 *       uint32_t(*s[])(uint32_t) = {bmw_small_s1, bmw_small_s2, bmw_small_s3, bmw_small_s0};
632 *       uint32_t r;
633 *       uint8_t i;
634 *       r = addelement(j, m, h);
635 *       i=15;
636 *       do{
637 *               r += s[i%4](q[j+i]);
638 *       }while(i--!=0);
639 *       return r;
640 *
641 * param j: r24
642 * param m: r22:r23
643 * param h: r20:r21
644 * param q: r18:r19
645 */
646 acc0 =  2
647 acc1 =  3
648 acc2 =  4
649 acc3 =  5
650 .global bmw_small_expand1
651 bmw_small_expand1:
652         push_range 28, 29
653         movw r28, r18
654         mov r18, r24
655         lsl r18
656         lsl r18
657         add r28, r18
658         adc r29, r1
659         rcall addelement
660         push_range 2, 5
661         push r16
662         ldi r16, 4
663         movw acc0, r22
664         movw acc2, r24
665 1:
666         ld r22, Y+
667         ld r23, Y+
668         ld r24, Y+
669         ld r25, Y+
670         rcall bmw_small_s1
671         add acc0, r22
672         adc acc1, r23
673         adc acc2, r24
674         adc acc3, r25
675         ld r22, Y+
676         ld r23, Y+
677         ld r24, Y+
678         ld r25, Y+
679         rcall bmw_small_s2
680         add acc0, r22
681         adc acc1, r23
682         adc acc2, r24
683         adc acc3, r25
684         ld r22, Y+
685         ld r23, Y+
686         ld r24, Y+
687         ld r25, Y+
688         rcall bmw_small_s3
689         add acc0, r22
690         adc acc1, r23
691         adc acc2, r24
692         adc acc3, r25
693         ld r22, Y+
694         ld r23, Y+
695         ld r24, Y+
696         ld r25, Y+
697         rcall bmw_small_s0
698         add acc0, r22
699         adc acc1, r23
700         adc acc2, r24
701         adc acc3, r25
702         dec r16
703         brne 1b
704 expand1_exit:
705         movw r22, acc0
706         movw r24, acc2
707         pop r16
708         pop_range 2, 5
709         pop_range 28, 29
710         ret
711
712 /*******************************************************************************
713 * uint32_t bmw_small_expand2(uint8_t j, const void* m, const void* h, const uint32_t* q){
714 *       uint32_t(*rf[])(uint32_t) = {bmw_small_r1, bmw_small_r2, bmw_small_r3,
715 *                                    bmw_small_r4, bmw_small_r5, bmw_small_r6,
716 *                                                            bmw_small_r7};
717 *       uint32_t r;
718 *       uint8_t i;
719 *       r = addelement(j, m, h);
720 *       for(i=0; i<14; i+=2){
721 *               r += q[j+i];
722 *       }
723 *       for(i=0; i<14; i+=2){
724 *               r += rf[i/2](q[j+i+1]);
725 *       }
726 *       r += bmw_small_s4(q[j+14]);
727 *       r += bmw_small_s5(q[j+15]);
728 *       return r;
729 * }
730 */
731 expand2_jumptable:
732         ret
733         rjmp bmw_small_r1
734         ret
735         rjmp bmw_small_r2
736         ret
737         rjmp bmw_small_r3
738         ret
739         rjmp bmw_small_r4
740         ret
741         rjmp bmw_small_r5
742         ret
743         rjmp bmw_small_r6
744         ret
745         rjmp bmw_small_r7
746         rjmp bmw_small_s4
747         rjmp bmw_small_s5
748
749 .global bmw_small_expand2
750 bmw_small_expand2:
751         push_range 28, 29
752         movw r28, r18
753         mov r18, r24
754         lsl r18
755         lsl r18
756         add r28, r18
757         adc r29, r1
758         rcall addelement
759         push_range 2, 5
760         push r16
761         ldi r16, 16
762         movw acc0, r22
763         movw acc2, r24
764         ldi r30, pm_lo8(expand2_jumptable)
765         ldi r31, pm_hi8(expand2_jumptable)
766 1:
767         ld r22, Y+
768         ld r23, Y+
769         ld r24, Y+
770         ld r25, Y+
771         push r30
772         push r31
773         icall
774         pop r31
775         pop r30
776         adiw r30, 1
777         add acc0, r22
778         adc acc1, r23
779         adc acc2, r24
780         adc acc3, r25
781         dec r16
782         brne 1b
783         rjmp expand1_exit
784
785 /*******************************************************************************
786 * void bmw_small_f1(uint32_t* q, const void* m, const void* h){
787 *       uint8_t i;
788 *       q[16] = bmw_small_expand1(0, m, h, q);
789 *       q[17] = bmw_small_expand1(1, m, h, q);
790 *       for(i=2; i<16; ++i){
791 *               q[16+i] = bmw_small_expand2(i, m, h, q);
792 *       }
793 * }
794 */
795 m0 =  2
796 m1 =  3
797 h0 =  4
798 h1 =  5
799 q0 =  6
800 q1 =  7
801 .global bmw_small_f1
802 bmw_small_f1:
803 ;       push_range 2, 7
804 ;       push_range 28, 29
805         push r16
806         movw q0, r24
807         movw m0, r22
808         movw h0, r20
809         movw r28, q0
810         adiw r28, 63
811         adiw r28, 1
812         clr r24
813         clr r25 /* not required */
814         movw r18, q0
815         rcall bmw_small_expand1
816         st Y+, r22
817         st Y+, r23
818         st Y+, r24
819         st Y+, r25
820         ldi r16, 1
821         mov r24, r16
822         clr r25 /* not required */
823         movw r22, m0
824         movw r20, h0
825         movw r18, q0
826         rcall bmw_small_expand1
827         st Y+, r22
828         st Y+, r23
829         st Y+, r24
830         st Y+, r25
831         inc r16
832 1:
833         mov r24, r16
834         movw r22, m0
835         movw r20, h0
836         movw r18, q0
837         rcall bmw_small_expand2
838         st Y+, r22
839         st Y+, r23
840         st Y+, r24
841         st Y+, r25
842         inc r16
843         cpi r16, 16
844         brne 1b
845         pop r16
846 ;       pop_range 28, 29
847 ;       pop_range 2, 7
848         ret
849
850 /*******************************************************************************
851 * uint16_t hack_table[5]   PROGMEM = { 0x0311, 0xDDB3, 0x2A79, 0x07AA, 0x51C2 };
852 * uint8_t  offset_table[5] PROGMEM = { 4+16, 6+16, 9+16, 12+16, 13+16 };
853 *
854 * void bmw_small_f0(uint32_t* h, const void* m, uint32_t* q){
855 *       uint16_t hack_reg;
856 *       uint8_t c,i,j;
857 *       uint32_t(*s[])(uint32_t)={ bmw_small_s0, bmw_small_s1, bmw_small_s2,
858 *                                  bmw_small_s3, bmw_small_s4 };
859 *       for(i=0; i<16; ++i){
860 *               ((uint32_t*)h)[i] ^= ((uint32_t*)m)[i];
861 *       }
862 *       dump_x(h, 16, 'T');
863 *       memset(q, 0, 4*16);
864 *       c=4;
865 *       do{
866 *               i=15;
867 *               j=pgm_read_byte(offset_table+c);
868 *               hack_reg=pgm_read_word(&(hack_table[c]));
869 *               do{
870 *                       if(hack_reg&1){
871 *                               q[i]-= h[j&15];
872 *                       }else{
873 *                               q[i]+= h[j&15];
874 *                       }
875 *                       --j;
876 *                       hack_reg>>= 1;
877 *               }while(i--!=0);
878 *       }while(c--!=0);
879 *       dump_x(q, 16, 'W');
880 *       for(i=0; i<16; ++i){
881 *               q[i] = s[i%5](q[i]);
882 *       }
883 *       for(i=0; i<16; ++i){
884 *               ((uint32_t*)h)[i] ^= ((uint32_t*)m)[i];
885 *       }
886 *       for(i=0; i<16; ++i){
887 *               q[i] += h[(i+1)&0xf];
888 *       }
889 * }
890 *
891 * param h: r24:r25
892 * param m: r22:r23
893 * param q: r20:r21
894 */
895 h0   =  24
896 h1   =  25
897 m0   =  22
898 m1   =  23
899 q0   =  20
900 q1   =  21
901 acc0 =  4
902 acc1 =  5
903 acc2 =  6
904 acc3 =  7
905 bcc0 =  8
906 bcc1 =  9
907 bcc2 = 10
908 bcc3 = 11
909 hack = 16
910
911 f0_helper:
912 20:
913         ldd acc0, Z+0
914         ldd acc1, Z+1
915         ldd acc2, Z+2
916         ldd acc3, Z+3
917         ld bcc0, X+
918         ld bcc1, X+
919         ld bcc2, X+
920         ld bcc3, X+
921         lsr r17
922         ror r16
923         brcs l20_sub
924         add acc0, bcc0
925         adc acc1, bcc1
926         adc acc2, bcc2
927         adc acc3, bcc3
928         rjmp l20_post
929 l20_sub:
930         sub acc0, bcc0
931         sbc acc1, bcc1
932         sbc acc2, bcc2
933         sbc acc3, bcc3
934 l20_post:
935         st Z+, acc0
936         st Z+, acc1
937         st Z+, acc2
938         st Z+, acc3
939         dec r18
940         brne 20b
941         ret
942
943 f0_jumptable:
944         rjmp bmw_small_s0
945         rjmp bmw_small_s1
946         rjmp bmw_small_s2
947         rjmp bmw_small_s3
948         rjmp bmw_small_s4
949         rjmp bmw_small_s0
950         rjmp bmw_small_s1
951         rjmp bmw_small_s2
952         rjmp bmw_small_s3
953         rjmp bmw_small_s4
954         rjmp bmw_small_s0
955         rjmp bmw_small_s1
956         rjmp bmw_small_s2
957         rjmp bmw_small_s3
958         rjmp bmw_small_s4
959         rjmp bmw_small_s0
960
961 .global bmw_small_f0
962 bmw_small_f0:
963 ;       push_range 28, 29
964 ;    push_range 4, 11
965 ;    push_range 16, 17
966     /* h[i] ^= m[i]; q[i]= 0 */
967         movw r26, h0 ; h
968         movw r30, m0 ; m
969         movw r28, q0 ; q
970         ldi r18, 64
971 1:  ld r0, X
972     ld r19, Z+
973     eor r0, r19
974     st X+, r0
975     st Y+, r1
976     dec r18
977     brne 1b
978 ;------
979     ldi r17, 0x88
980     ldi r16, 0xC0
981     movw r26, h0 ; X = h
982     adiw r26, 5*4
983     ldi r18, 16-5
984     movw r30, q0 ; Z = q
985     rcall f0_helper
986     movw r26, h0 ; X = h
987     ldi r18,    5
988     rcall f0_helper
989 ;---
990     ldi r17, 0xCD
991     ldi r16, 0xBB
992     movw r26, h0 ; X = h
993     adiw r26, 7*4
994     ldi r18, 16-7
995     movw r30, q0 ; Z = q
996     rcall f0_helper
997     movw r26, h0 ; X = h
998     ldi r18,    7
999     rcall f0_helper
1000 ;---
1001     ldi r17, 0x9E
1002     ldi r16, 0x54
1003     movw r26, h0 ; X = h
1004     adiw r26, 10*4
1005     ldi r18, 16-10
1006     movw r30, q0 ; Z = q
1007     rcall f0_helper
1008     movw r26, h0 ; X = h
1009     ldi r18,   10
1010     rcall f0_helper
1011 ;---
1012     ldi r17, 0x55
1013     ldi r16, 0xE0
1014     movw r26, h0 ; X = h
1015     adiw r26, 13*4
1016     ldi r18, 16-13
1017     movw r30, q0 ; Z = q
1018     rcall f0_helper
1019     movw r26, h0 ; X = h
1020     ldi r18,  13
1021     rcall f0_helper
1022 ;---
1023     ldi r17, 0x43
1024     ldi r16, 0x8A
1025     movw r26, h0 ; X = h
1026     adiw r26, 14*4
1027     ldi r18, 16-14
1028     movw r30, q0 ; Z = q
1029     rcall f0_helper
1030     movw r26, h0 ; X = h
1031     ldi r18,  14
1032     rcall f0_helper
1033 ;--------------- h[i] ^= m[i]
1034         movw r26, h0 ; h
1035         movw r30, m0 ; m
1036         ldi r18, 64
1037 25: ld r0, X
1038     ld r19, Z+
1039     eor r0, r19
1040     st X+, r0
1041     dec r18
1042     brne 25b
1043 ;--------------- q[i] = s[i%5](q[i])
1044         ldi r16, 16
1045         ldi r30, pm_lo8(f0_jumptable)
1046         ldi r31, pm_hi8(f0_jumptable)
1047     movw bcc0, r30
1048     movw bcc2, h0 ; h
1049     movw acc0, q0 ; q
1050     movw r28,  q0 ; Y = q
1051 30:
1052         ldd r22, Y+0
1053         ldd r23, Y+1
1054         ldd r24, Y+2
1055         ldd r25, Y+3
1056         icall
1057         st Y+, r22
1058         st Y+, r23
1059         st Y+, r24
1060         st Y+, r25
1061         movw r30, bcc0
1062         adiw r30, 1
1063         movw bcc0, r30
1064         dec r16
1065         brne 30b
1066 ;--------------- q[i] += h[(i+1)%16]
1067         movw r30, acc0 ; q
1068         movw r26, bcc2 ; h
1069         adiw r26, 4
1070         ldi r18, 15
1071 40:
1072         ld acc0, Z
1073         ld acc1, X+
1074         add acc0, acc1
1075         st Z+, acc0
1076         ld acc0, Z
1077         ld acc1, X+
1078         adc acc0, acc1
1079         st Z+, acc0
1080         ld acc0, Z
1081         ld acc1, X+
1082         adc acc0, acc1
1083         st Z+, acc0
1084         ld acc0, Z
1085         ld acc1, X+
1086         adc acc0, acc1
1087         st Z+, acc0
1088         dec r18
1089         brne 40b
1090         movw r26, bcc2 ; h
1091         ld acc0, Z
1092         ld acc1, X+
1093         add acc0, acc1
1094         st Z+, acc0
1095         ld acc0, Z
1096         ld acc1, X+
1097         adc acc0, acc1
1098         st Z+, acc0
1099         ld acc0, Z
1100         ld acc1, X+
1101         adc acc0, acc1
1102         st Z+, acc0
1103         ld acc0, Z
1104         ld acc1, X+
1105         adc acc0, acc1
1106         st Z+, acc0
1107
1108 ;   pop_range 16, 17
1109 ;   pop_range 4, 11
1110 ;       pop_range 28, 29
1111     ret
1112
1113 /*******************************************************************************
1114 * void bmw_small_f2(uint32_t* h, const uint32_t* q, const void* m){
1115 *       uint32_t xl=0, xh;
1116 *       uint8_t i;
1117 *       for(i=16;i<24;++i){
1118 *               xl ^= q[i];
1119 *       }
1120 *       xh = xl;
1121 *       for(i=24;i<32;++i){
1122 *               xh ^= q[i];
1123 *       }
1124 *       memcpy(h, m, 16*4);
1125 *       h[0] ^= SHL32(xh, 5) ^ SHR32(q[16], 5);
1126 *       h[5] ^= SHL32(xh, 6) ^ SHR32(q[21], 6);
1127 *       h[3] ^= SHR32(xh, 1) ^ SHL32(q[19], 5);
1128 *       h[4] ^= SHR32(xh, 3) ^ q[20];
1129 *       h[6] ^= SHR32(xh, 4) ^ SHL32(q[22], 6);
1130 *       h[2] ^= SHR32(xh, 5) ^ SHL32(q[18], 5);
1131 *       h[1] ^= SHR32(xh, 7) ^ SHL32(q[17], 8);
1132 *       h[7] ^= SHR32(xh,11) ^ SHL32(q[23], 2);
1133 *       for(i=0; i<8; ++i){
1134 *               h[i] += xl ^ q[24+i] ^ q[i];
1135 *       }
1136 *       for(i=0; i<8; ++i){
1137 *               h[8+i] ^= xh ^ q[24+i];
1138 *               h[8+i] += ROTL32(h[(4+i)%8],i+9);
1139 *       }
1140 *       h[11] += SHL32(xl, 4) ^ q[18] ^ q[11];
1141 *       h[10] += SHL32(xl, 6) ^ q[17] ^ q[10];
1142 *       h[ 8] += SHL32(xl, 8) ^ q[23] ^ q[ 8];
1143 *       h[15] += SHR32(xl, 2) ^ q[22] ^ q[15];
1144 *       h[12] += SHR32(xl, 3) ^ q[19] ^ q[12];
1145 *       h[13] += SHR32(xl, 4) ^ q[20] ^ q[13];
1146 *       h[ 9] += SHR32(xl, 6) ^ q[16] ^ q[ 9];
1147 *       h[14] += SHR32(xl, 7) ^ q[21] ^ q[14];
1148 * }
1149 *
1150 * param h: r24:r25
1151 * param q: r22:r23
1152 * param m: r20:r21
1153 */
1154 xl0 =  2
1155 xl1 =  3
1156 xl2 =  4
1157 xl3 =  5
1158 xh0 =  6
1159 xh1 =  7
1160 xh2 =  8
1161 xh3 =  9
1162 q0  = 10
1163 q1  = 11
1164 h0  = 12
1165 h1  = 13
1166 t0  = 14
1167 t1  = 15
1168 t2  = 16
1169 t3  = 17
1170
1171
1172 .macro modify_h_2 addr:req
1173         ldd r22, Y+\addr*4+0
1174         ldd r23, Y+\addr*4+1
1175         ldd r24, Y+\addr*4+2
1176         ldd r25, Y+\addr*4+3
1177         eor r22, t0
1178         eor r23, t1
1179         eor r24, t2
1180         eor r25, t3
1181         ldd r0, Z+\addr*4+0
1182         add r0, r22
1183         std Z+\addr*4+0, r0
1184         ldd r0, Z+\addr*4+1
1185         adc r0, r23
1186         std Z+\addr*4+1, r0
1187         ldd r0, Z+\addr*4+2
1188         adc r0, r24
1189         std Z+\addr*4+2, r0
1190         ldd r0, Z+\addr*4+3
1191         adc r0, r25
1192         std Z+\addr*4+3, r0
1193 .endm
1194
1195 tshiftr:
1196         lsr t3
1197         ror t2
1198         ror t1
1199         ror t0
1200         dec r20
1201         brne tshiftr
1202         ret
1203
1204 tshiftl:
1205         lsl t0
1206         rol t1
1207         rol t2
1208         rol t3
1209         dec r20
1210         brne tshiftl
1211         ret
1212
1213 .global bmw_small_f2
1214 bmw_small_f2:
1215     /* memcpy(h, m, 64) */
1216         movw r26, r24
1217         movw r30, r20
1218         ldi r18, 64
1219 1:      ld r0, Z+
1220         st X+, r0
1221         dec r18
1222         brne 1b
1223 ;       push_range 28, 29
1224 ;       push_range  2, 17
1225         movw q0, r22
1226         movw h0, r24
1227         /* calc xl */
1228 /*      for(i=16;i<24;++i){
1229                 xl ^= q[i];
1230         }
1231 */
1232         movw r26, q0
1233         adiw r26, 63
1234         adiw r26, 1 ; X points at q[16]
1235         ld xl0, X+
1236         ld xl1, X+
1237         ld xl2, X+
1238         ld xl3, X+
1239         ldi r18, 8-1
1240 20: ld r0, X+
1241         eor xl0, r0
1242         ld r0, X+
1243         eor xl1, r0
1244         ld r0, X+
1245         eor xl2, r0
1246         ld r0, X+
1247         eor xl3, r0
1248         dec r18
1249         brne 20b
1250         /* calc xh */
1251 /*  xh = xl
1252         for(i=24;i<32;++i){
1253                 xh ^= q[i];
1254         }
1255 */
1256         movw xh0, xl0
1257         movw xh2, xl2
1258         ldi r18, 8
1259 25: ld r0, X+
1260         eor xh0, r0
1261         ld r0, X+
1262         eor xh1, r0
1263         ld r0, X+
1264         eor xh2, r0
1265         ld r0, X+
1266         eor xh3, r0
1267         dec r18
1268         brne 25b
1269 /* h[0]..h[7] */
1270         movw r30, h0
1271         movw r28, q0
1272         adiw r28, 60 ; Y points at q[15]
1273 /*      h[0] ^= SHL32(xh, 5) ^ SHR32(q[16], 5); */
1274         movw t0, xh0
1275         movw t2, xh2
1276         ldi r20, 5
1277         rcall tshiftl
1278         ldd r22, Y+4
1279         ldd r23, Y+5
1280         ldd r24, Y+6
1281         ldd r25, Y+7
1282         ldi r20, 5
1283         rcall shiftr32
1284         eor r22, t0
1285         eor r23, t1
1286         eor r24, t2
1287         eor r25, t3
1288         ldd r0, Z+0
1289         eor r22, r0
1290         ldd r0, Z+1
1291         eor r23, r0
1292         ldd r0, Z+2
1293         eor r24, r0
1294         ldd r0, Z+3
1295         eor r25, r0
1296         std Z+0, r22
1297         std Z+1, r23
1298         std Z+2, r24
1299         std Z+3, r25
1300 /*      h[5] ^= SHL32(xh, 6) ^ SHR32(q[21], 6); */
1301         lsl t0
1302         rol t1
1303         rol t2
1304         rol t3
1305         ldd r22, Y+24
1306         ldd r23, Y+25
1307         ldd r24, Y+26
1308         ldd r25, Y+27
1309         ldi r20, 6
1310         rcall shiftr32
1311         eor r22, t0
1312         eor r23, t1
1313         eor r24, t2
1314         eor r25, t3
1315         ldd r0, Z+20
1316         eor r22, r0
1317         ldd r0, Z+21
1318         eor r23, r0
1319         ldd r0, Z+22
1320         eor r24, r0
1321         ldd r0, Z+23
1322         eor r25, r0
1323         std Z+20, r22
1324         std Z+21, r23
1325         std Z+22, r24
1326         std Z+23, r25
1327 /*      h[3] ^= SHR32(xh, 1) ^ SHL32(q[19], 5); */
1328         movw t0, xh0
1329         movw t2, xh2
1330         lsr t3
1331         ror t2
1332         ror t1
1333         ror t0
1334         ldd r22, Y+16
1335         ldd r23, Y+17
1336         ldd r24, Y+18
1337         ldd r25, Y+19
1338         ldi r20, 5
1339         rcall shiftl32
1340         eor r22, t0
1341         eor r23, t1
1342         eor r24, t2
1343         eor r25, t3
1344         ldd r0, Z+12
1345         eor r22, r0
1346         ldd r0, Z+13
1347         eor r23, r0
1348         ldd r0, Z+14
1349         eor r24, r0
1350         ldd r0, Z+15
1351         eor r25, r0
1352         std Z+12, r22
1353         std Z+13, r23
1354         std Z+14, r24
1355         std Z+15, r25
1356 /*      h[4] ^= SHR32(xh, 3) ^ q[20]; */
1357         ldi r20, 2
1358         rcall tshiftr
1359         ldd r22, Y+20
1360         ldd r23, Y+21
1361         ldd r24, Y+22
1362         ldd r25, Y+23
1363         eor r22, t0
1364         eor r23, t1
1365         eor r24, t2
1366         eor r25, t3
1367         ldd r0, Z+16
1368         eor r22, r0
1369         ldd r0, Z+17
1370         eor r23, r0
1371         ldd r0, Z+18
1372         eor r24, r0
1373         ldd r0, Z+19
1374         eor r25, r0
1375         std Z+16, r22
1376         std Z+17, r23
1377         std Z+18, r24
1378         std Z+19, r25
1379 /*      h[6] ^= SHR32(xh, 4) ^ SHL32(q[22], 6); */
1380         lsr t3
1381         ror t2
1382         ror t1
1383         ror t0
1384         ldd r22, Y+28
1385         ldd r23, Y+29
1386         ldd r24, Y+30
1387         ldd r25, Y+31
1388         ldi r20, 6
1389         rcall shiftl32
1390         eor r22, t0
1391         eor r23, t1
1392         eor r24, t2
1393         eor r25, t3
1394         ldd r0, Z+24
1395         eor r22, r0
1396         ldd r0, Z+25
1397         eor r23, r0
1398         ldd r0, Z+26
1399         eor r24, r0
1400         ldd r0, Z+27
1401         eor r25, r0
1402         std Z+24, r22
1403         std Z+25, r23
1404         std Z+26, r24
1405         std Z+27, r25
1406 /*      h[2] ^= SHR32(xh, 5) ^ SHL32(q[18], 5); */
1407         lsr t3
1408         ror t2
1409         ror t1
1410         ror t0
1411         ldd r22, Y+12
1412         ldd r23, Y+13
1413         ldd r24, Y+14
1414         ldd r25, Y+15
1415         ldi r20, 5
1416         rcall shiftl32
1417         eor r22, t0
1418         eor r23, t1
1419         eor r24, t2
1420         eor r25, t3
1421         ldd r0, Z+8
1422         eor r22, r0
1423         ldd r0, Z+9
1424         eor r23, r0
1425         ldd r0, Z+10
1426         eor r24, r0
1427         ldd r0, Z+11
1428         eor r25, r0
1429         std Z+8 , r22
1430         std Z+9 , r23
1431         std Z+10, r24
1432         std Z+11, r25
1433 /*      h[1] ^= SHR32(xh, 7) ^ SHL32(q[17], 8); */
1434         ldi r20, 2
1435         rcall tshiftr
1436         ldd r23, Y+8
1437         ldd r24, Y+9
1438         ldd r25, Y+10
1439         mov r22, t0
1440         eor r23, t1
1441         eor r24, t2
1442         eor r25, t3
1443         ldd r0, Z+4
1444         eor r22, r0
1445         ldd r0, Z+5
1446         eor r23, r0
1447         ldd r0, Z+6
1448         eor r24, r0
1449         ldd r0, Z+7
1450         eor r25, r0
1451         std Z+4 , r22
1452         std Z+5 , r23
1453         std Z+6 , r24
1454         std Z+7 , r25
1455 /*      h[7] ^= SHR32(xh,11) ^ SHL32(q[23], 2); */
1456         ldi r20, 4
1457         rcall tshiftr
1458         ldd r22, Y+32
1459         ldd r23, Y+33
1460         ldd r24, Y+34
1461         ldd r25, Y+35
1462         ldi r20, 2
1463         rcall shiftl32
1464         eor r22, t0
1465         eor r23, t1
1466         eor r24, t2
1467         eor r25, t3
1468         ldd r0, Z+28
1469         eor r22, r0
1470         ldd r0, Z+29
1471         eor r23, r0
1472         ldd r0, Z+30
1473         eor r24, r0
1474         ldd r0, Z+31
1475         eor r25, r0
1476         std Z+28, r22
1477         std Z+29, r23
1478         std Z+30, r24
1479         std Z+31, r25
1480 /*      for(i=0; i<8; ++i){
1481 *               h[i] += xl ^ q[24+i] ^ q[i];
1482 *       }
1483 */
1484         movw r26, q0
1485         movw r28, q0
1486         adiw r28, 63
1487         adiw r28, 24*4-63
1488         ldi r18, 8
1489 10:
1490         movw t0, xl0
1491         movw t2, xl2
1492         ld r0, X+
1493         eor t0, r0
1494         ld r0, X+
1495         eor t1, r0
1496         ld r0, X+
1497         eor t2, r0
1498         ld r0, X+
1499         eor t3, r0
1500         ld r0, Y+
1501         eor t0, r0
1502         ld r0, Y+
1503         eor t1, r0
1504         ld r0, Y+
1505         eor t2, r0
1506         ld r0, Y+
1507         eor t3, r0
1508         ldd r22, Z+0
1509         ldd r23, Z+1
1510         ldd r24, Z+2
1511         ldd r25, Z+3
1512         add r22, t0
1513         adc r23, t1
1514         adc r24, t2
1515         adc r25, t3
1516         st Z+, r22
1517         st Z+, r23
1518         st Z+, r24
1519         st Z+, r25
1520         dec r18
1521         brne 10b
1522         ; Z points to h[8]
1523 /*      for(i=0; i<8; ++i){
1524                 h[8+i] ^= xh ^ q[24+i];
1525                 h[8+i] += ROTL32(h[(4+i)%8],i+9);
1526         }
1527 */
1528         ; Z points at h[8]
1529 ;       clr r18
1530         sbiw r28, 8*4 ; Y points at q[24]
1531         movw r26, r30
1532         sbiw r26, 4*4 ; X points at h[4]
1533 15:
1534         ldd t0, Z+0
1535         ldd t1, Z+1
1536         ldd t2, Z+2
1537         ldd t3, Z+3
1538         eor t0, xh0
1539         eor t1, xh1
1540         eor t2, xh2
1541         eor t3, xh3
1542         ld r0, Y+
1543         eor t0, r0
1544         ld r0, Y+
1545         eor t1, r0
1546         ld r0, Y+
1547         eor t2, r0
1548         ld r0, Y+
1549         eor t3, r0
1550         ld r22, X+
1551         ld r23, X+
1552         ld r24, X+
1553         ld r25, X+
1554         mov r20, r18
1555         rcall rotl32p9
1556         add t0, r22
1557         adc t1, r23
1558         adc t2, r24
1559         adc t3, r25
1560         st Z+, t0
1561         st Z+, t1
1562         st Z+, t2
1563         st Z+, t3
1564         inc r18
1565         cpi r18, 4
1566         brne 16f
1567         movw r26, h0
1568 16:
1569         sbrs r18, 3
1570         rjmp 15b
1571         sbiw r30, 4*8 ; adjust Z to point at h[8]
1572         sbiw r28, 16*4-1
1573         sbiw r28, 1   ; adjust Y to point at q[16]
1574         movw r26, r28
1575         sbiw r26, 7*4 ; adjust X to point at q[9]
1576         ldi r18, 7*4
1577 20: /* now we do the memxor stuff */
1578         ld t0, X
1579         ld t1, Y+
1580         eor t0, t1
1581         st X+, t0
1582         dec r18
1583         brne 20b
1584         ; X points at q[16]
1585         ; Y points at q[23]
1586         sbiw r26, 4*8 ; X points at q[8]
1587
1588         clr t0
1589         mov t1, xl0
1590         mov t2, xl1
1591         mov t3, xl2
1592 /*      h[ 8] += SHL32(xl, 8) ^ q[23] ^ q[ 8]; */
1593         ld r22, X+
1594         ld r23, X+
1595         ld r24, X+
1596         ld r25, X+
1597         ld r0, Y+
1598         eor r22, r0
1599         ld r0, Y+
1600         eor r23, r0
1601         ld r0, Y+
1602         eor r24, r0
1603         ld r0, Y+
1604         eor r25, r0
1605         eor r22, t0
1606         eor r23, t1
1607         eor r24, t2
1608         eor r25, t3
1609         ld r0, Z
1610         add r0, r22
1611         st Z+, r0
1612         ld r0, Z
1613         adc r0, r23
1614         st Z+, r0
1615         ld r0, Z
1616         adc r0, r24
1617         st Z+, r0
1618         ld r0, Z
1619         adc r0, r25
1620         st Z+, r0
1621         movw r28, r26
1622         ; Z points at h[9]
1623         ; X points at q[9] but we won't need it anymore
1624         ; Y points at q[9]
1625 /*      h[11] += SHL32(xl, 4) ^ q[11]; */
1626         movw t0, xl0
1627         movw t2, xl2
1628         ldi r20, 4
1629         rcall tshiftl
1630         modify_h_2 2
1631 /*      h[10] += SHL32(xl, 6) ^ q[10]; */
1632         ldi r20, 2
1633         rcall tshiftl
1634         modify_h_2 1
1635 /*      h[15] += SHR32(xl, 2) ^ q[15]; */
1636         movw t0, xl0
1637         movw t2, xl2
1638         ldi r20, 2
1639         rcall tshiftr
1640         modify_h_2 6
1641 /*      h[12] += SHR32(xl, 3) ^ q[12]; */
1642         ldi r20, 1
1643         rcall tshiftr
1644         modify_h_2 3
1645 /*      h[13] += SHR32(xl, 4) ^ q[13]; */
1646         ldi r20, 1
1647         rcall tshiftr
1648         modify_h_2 4
1649 /*      h[ 9] += SHR32(xl, 6) ^ q[ 9]; */
1650         ldi r20, 2
1651         rcall tshiftr
1652         modify_h_2 0
1653 /*      h[14] += SHR32(xl, 7) ^ q[14]; */
1654         ldi r20, 1
1655         rcall tshiftr
1656         modify_h_2 5
1657 bmw_small_f2_exit:
1658 ;       pop_range  2, 17
1659 ;       pop_range 28, 29
1660         ret
1661
1662 cli_putb:
1663         push r2
1664         push_range 18, 26
1665         push_range 30, 31
1666         mov r2, r24
1667         swap r24
1668         andi r24, 0xf
1669         ldi r30, lo8(hextable)
1670         ldi r31, hi8(hextable)
1671         add r30, r24
1672         adc r31, r1
1673         lpm r24, Z
1674         clr r25
1675         call cli_putc
1676         mov r24, r2
1677         andi r24, 0xf
1678         ldi r30, lo8(hextable)
1679         ldi r31, hi8(hextable)
1680         add r30, r24
1681         adc r31, r1
1682         lpm r24, Z
1683         clr r25
1684         call cli_putc
1685         pop_range 30, 31
1686         pop_range 18, 26
1687         pop r2
1688         ret
1689 hextable:
1690         .byte '0', '1', '2', '3', '4', '5', '6', '7'
1691         .byte '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
1692
1693 cli_putchar:
1694         push_range 18, 31
1695         call cli_putc
1696         pop_range 18, 31
1697         ret
1698
1699 /*******************************************************************************
1700 * void bmw_small_nextBlock(bmw_small_ctx_t* ctx, const void* block){
1701 *       uint32_t q[32];
1702 *       dump_x(block, 16, 'M');
1703 *       bmw_small_f0(ctx->h, block, q);
1704 *       dump_x(q, 16, 'Q');
1705 *       bmw_small_f1(q, block, ctx->h);
1706 *       dump_x(q, 32, 'Q');
1707 *       bmw_small_f2(ctx->h, q, block);
1708 *       ctx->counter += 1;
1709 *       ctx_dump(ctx);
1710 * }
1711 *
1712 * param ctx:   r24:r25
1713 * param block: r22:r23
1714 */
1715 h0 =  2
1716 h1 =  3
1717 b0 =  4
1718 b1 =  5
1719 q0 =  6
1720 q1 =  7
1721 .global bmw_small_nextBlock
1722 bmw_small_nextBlock:
1723         push_range 28, 29
1724         push_range  2, 17
1725         stack_alloc_large 32*4, 30, 31
1726         adiw r30, 1
1727         movw q0, r30
1728         movw h0, r24
1729         movw b0, r22
1730         /* increment counter */
1731         movw r30, r24
1732         adiw r30, 60
1733         ldd r22, Z+4
1734         ldd r23, Z+5
1735         ldd r24, Z+6
1736         ldd r25, Z+7
1737         ldi r21, 1
1738         add r22, r21
1739         adc r23, r1
1740         adc r24, r1
1741         adc r25, r1
1742         std Z+4, r22
1743         std Z+5, r23
1744         std Z+6, r24
1745         std Z+7, r25
1746         /* call bmw_small_f0(ctx->h, block, q) */
1747         movw r24, h0
1748         movw r22, b0
1749         movw r20, q0
1750         push_ q1, q0, b1, b0, h1, h0
1751         rcall bmw_small_f0
1752         /*      call bmw_small_f1(q, block, ctx->h) */
1753         pop_ 20, 21, 22, 23, 24, 25,
1754         push_ 21, 20, 25, 24, 23, 22
1755         rcall bmw_small_f1
1756         /*      call bmw_small_f2(ctx->h, q, block) */
1757         pop_ 20, 21, 22, 23, 24, 25,
1758         rcall bmw_small_f2
1759         stack_free_large3 32*4
1760         pop_range  2, 17
1761         pop_range 28, 29
1762         ret
1763
1764
1765
1766
1767
1768
1769