]> git.cryptolib.org Git - avr-crypto-lib.git/blob - skein/threefish512_enc_asm.S
optimizing norx32
[avr-crypto-lib.git] / skein / threefish512_enc_asm.S
1 /* threefish512_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 threefish512_init(const void *key, const void *tweak, threefish512_ctx_t *ctx){
43         memcpy(ctx->k, key, 8*8);
44         memcpy(ctx->t, tweak, 2*8);
45         uint8_t i;
46         ctx->k[8] = THREEFISH_KEY_CONST;
47         for(i=0; i<8; ++i){
48                 ctx->k[8] ^= 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 threefish512_init
59 threefish512_init:
60         push_range 14, 17
61         movw r30, r20
62         movw r26, r24
63         ldi r24, 8
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_8(void *data){
182         uint64_t t;
183         t = X(0);
184         X(0) = X(2);
185         X(2) = X(4);
186         X(4) = X(6);
187         X(6) = t;
188         t = X(3);
189         X(3) = X(7);
190         X(7) = t;
191 }
192 void add_key_8(void *data, const threefish512_ctx_t *ctx, uint8_t s){
193         uint8_t i;
194         for(i=0; i<5; ++i){
195                 X(i) += ctx->k[(s+i)%9];
196         }
197         X(5) += ctx->k[(s+5)%9] + ctx->t[s%3];
198         X(6) += ctx->k[(s+6)%9] + ctx->t[(s+1)%3];
199         X(7) += ctx->k[(s+7)%9] + s;
200 }
201 void threefish512_enc(void *data, const threefish512_ctx_t *ctx){
202         uint8_t i=0,s=0;
203         uint8_t r0[8] = {38, 48, 34, 26, 33, 39, 29, 33};
204         uint8_t r1[8] = {30, 20, 14, 12, 49, 27, 26, 51};
205         uint8_t r2[8] = {50, 43, 15, 58,  8, 41, 11, 39};
206         uint8_t r3[8] = {53, 31, 27,  7, 42, 14,  9, 35};
207         do{
208                 if(i%4==0){
209                         add_key_8(data, ctx, s);
210                         ++s;
211                 }
212                 threefish_mix((uint8_t*)data +  0, r0[i%8]);
213                 threefish_mix((uint8_t*)data + 16, r1[i%8]);
214                 threefish_mix((uint8_t*)data + 32, r2[i%8]);
215                 threefish_mix((uint8_t*)data + 48, r3[i%8]);
216                 permute_8(data);
217                 ++i;
218         }while(i!=72);
219         add_key_8(data, ctx, s);
220 }
221
222 */
223 I     =  2
224 S     =  3
225 DATA0 =  4
226 DATA1 =  5
227 CTX0  =  6
228 CTX1  =  7
229 IDX0  =  8
230 IDX1  =  9
231 IDX2  = 10
232 IDX3  = 11
233 IDX4  = 12
234 IDX5  = 13
235 IDX6  = 14
236 IDX7  = 15
237 /*
238  * param data:  r24:r25
239  * param ctx:   r22:r23
240  */
241 .global threefish512_enc
242 threefish512_enc:
243         push r28
244         push r29
245         push_range 2, 17
246         movw DATA0, r24
247         movw CTX0, r22
248         clr I
249         clr S
250 1:
251         mov r30,  I
252         andi r30, 0x03
253         breq 2f
254         rjmp 4f
255 2:
256         ldi r30, lo8(threefish512_slut9)
257         ldi r31, hi8(threefish512_slut9)
258         add r30, S
259         adc r31, r1
260         lpm IDX0, Z+
261         lpm IDX1, Z+
262         lpm IDX2, Z+
263         lpm IDX3, Z+
264         lpm IDX4, Z+
265         lpm IDX5, Z+
266         lpm IDX6, Z+
267         lpm IDX7, Z
268         movw r30, CTX0
269         movw r26, DATA0
270         add r30, IDX0
271         adc r31, r1
272         rcall add_z_to_x8
273         movw r30, CTX0
274         add r30, IDX1
275         adc r31, r1
276         rcall add_z_to_x8
277         movw r30, CTX0
278         add r30, IDX2
279         adc r31, r1
280         rcall add_z_to_x8
281         movw r30, CTX0
282         add r30, IDX3
283         adc r31, r1
284         rcall add_z_to_x8
285         movw r30, CTX0
286         add r30, IDX4
287         adc r31, r1
288         rcall add_z_to_x8
289         movw r30, CTX0
290         add r30, IDX5
291         adc r31, r1
292         rcall add_z_to_x8
293         movw r30, CTX0
294         add r30, IDX6
295         adc r31, r1
296         rcall add_z_to_x8
297         movw r30, CTX0
298         add r30, IDX7
299         adc r31, r1
300         rcall add_z_to_x8
301
302         /* now the remaining key */
303         sbiw r26, 3*8
304         ldi r30, lo8(threefish512_slut3)
305         ldi r31, hi8(threefish512_slut3)
306         add r30, S
307         adc r31, r1
308         lpm IDX0, Z+
309         lpm IDX1, Z
310         movw r30, CTX0
311         adiw r30, 7*8 /* make Z pointing to (extended tweak) */
312         adiw r30, 2*8
313         movw IDX2, r30
314         add r30, IDX0
315         adc r31, r1
316         rcall add_z_to_x8
317         movw r30, IDX2
318         add r30, IDX1
319         adc r31, r1
320         rcall add_z_to_x8
321         ld r0, X
322         add r0, S
323         st X+, r0
324         ld r0, X
325         adc r0, r1
326         st X+, r0
327         ld r0, X
328         adc r0, r1
329         st X+, r0
330         ld r0, X
331         adc r0, r1
332         st X+, r0
333         ld r0, X
334         adc r0, r1
335         st X+, r0
336         ld r0, X
337         adc r0, r1
338         st X+, r0
339         ld r0, X
340         adc r0, r1
341         st X+, r0
342         ld r0, X
343         adc r0, r1
344         st X+, r0
345         inc S
346         mov r26, S
347         cpi r26, 19
348         brmi 4f
349 exit:
350         pop_range 2, 17
351         pop r29
352         pop r28
353         ret
354 4:
355         /* call mix */
356         ldi r30, lo8(threefish512_rc0)
357         ldi r31, hi8(threefish512_rc0)
358         mov r26, I
359         andi r26, 0x07
360         add r30, r26
361         adc r31, r1
362         lpm r22, Z
363         adiw r30, 8
364         lpm IDX0, Z
365         adiw r30, 8
366         lpm IDX1, Z
367         push IDX1
368         adiw r30, 8
369         lpm IDX1, Z
370
371         movw r24, DATA0
372         call threefish_mix_asm /* no rcall? */
373         movw r24, DATA0
374         adiw r24, 16
375         mov r22, IDX0
376         call threefish_mix_asm /* no rcall? */
377         movw r24, DATA0
378         adiw r24, 32
379         pop r22
380         ;mov r22, IDX0
381         call threefish_mix_asm /* no rcall? */
382         movw r24, DATA0
383         adiw r24, 48
384         mov r22, IDX1
385         call threefish_mix_asm /* no rcall? */
386         /* now the permutation */
387         movw r26, DATA0
388         movw r30, DATA0
389         adiw r30, 6*8
390         rcall xchg_zx8
391         movw r26, DATA0
392         movw r30, DATA0
393         adiw r30, 2*8
394         rcall xchg_zx8
395         movw r26, DATA0
396         adiw r26, 2*8
397         movw r30, DATA0
398         adiw r30, 4*8
399         rcall xchg_zx8
400         movw r26, DATA0
401         adiw r26, 3*8
402         movw r30, DATA0
403         adiw r30, 7*8
404         rcall xchg_zx8
405         inc I
406         rjmp 1b
407
408 threefish512_slut9:
409         .byte 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38
410         .byte 0x40, 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30
411         .byte 0x38, 0x40, 0x00, 0x08, 0x10, 0x18, 0x20, 0x28
412         .byte 0x30, 0x38, 0x40
413 threefish512_slut3:
414         .byte 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08
415         .byte 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00
416         .byte 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08
417
418 /* old round constants
419 threefish512_rc0: .byte 0x5a, 0x60, 0x42, 0x32, 0x41, 0x59, 0x4b, 0x41
420 threefish512_rc1: .byte 0x4a, 0x24, 0x2a, 0x14, 0x61, 0x33, 0x32, 0x63
421 threefish512_rc2: .byte 0x62, 0x53, 0x29, 0x72, 0x10, 0x51, 0x13, 0x59
422 threefish512_rc3: .byte 0x7b, 0x49, 0x33, 0x19, 0x52, 0x2a, 0x11, 0x43
423 */
424 threefish512_rc0:  .byte 0x6a, 0x41, 0x21, 0x54, 0x59, 0x2b, 0x31, 0x10
425 threefish512_rc1:  .byte 0x44, 0x33, 0x61, 0x11, 0x4a, 0x62, 0x4b, 0x43
426 threefish512_rc2:  .byte 0x23, 0x2a, 0x44, 0x7a, 0x42, 0x12, 0x59, 0x70
427 threefish512_rc3:  .byte 0x5b, 0x52, 0x59, 0x70, 0x30, 0x21, 0x53, 0x3a
428 add_z_to_x8:
429         ld r0, Z+
430         ld r1, X
431         add r1, r0
432         st X+, r1
433         ld r0, Z+
434         ld r1, X
435         adc r1, r0
436         st X+, r1
437         ld r0, Z+
438         ld r1, X
439         adc r1, r0
440         st X+, r1
441         ld r0, Z+
442         ld r1, X
443         adc r1, r0
444         st X+, r1
445         ld r0, Z+
446         ld r1, X
447         adc r1, r0
448         st X+, r1
449         ld r0, Z+
450         ld r1, X
451         adc r1, r0
452         st X+, r1
453         ld r0, Z+
454         ld r1, X
455         adc r1, r0
456         st X+, r1
457         ld r0, Z+
458         ld r1, X
459         adc r1, r0
460         st X+, r1
461         clr r1
462         ret
463
464 T0 = IDX0
465 T1 = 0
466 CNT = 24
467 xchg_zx8:
468         ldi CNT, 8
469 1:      ld T0, X
470         ld T1, Z
471         st X+, T1
472         st Z+, T0
473         dec CNT
474         brne 1b
475         ret
476
477
478