]> git.cryptolib.org Git - avr-crypto-lib.git/blob - skein/skein256_asm.S
fixing E-Mail-Address & Copyright
[avr-crypto-lib.git] / skein / skein256_asm.S
1 /* skein256_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  * \author  Daniel Otte
21  * \email   bg@nerilex.org
22  * \date    2009-03-16
23  * \license GPLv3 or later
24  */
25
26 #include "avr-asm-macros.S"
27
28 /******************************************************************************/
29 /*
30 void skein256_init(skein256_ctx_t *ctx, uint16_t outsize_b){
31         skein_config_t conf;
32         uint8_t null[UBI256_BLOCKSIZE_B];
33         memset(null, 0, UBI256_BLOCKSIZE_B);
34         memset(&conf, 0, sizeof(skein_config_t));
35         conf.schema[0] = 'S';
36         conf.schema[1] = 'H';
37         conf.schema[2] = 'A';
38         conf.schema[3] = '3';
39         conf.version = 1;
40         conf.out_length = outsize_b;
41         ctx->outsize_b = outsize_b;
42         ubi256_init(&(ctx->ubictx), null, UBI_TYPE_CFG);
43         ubi256_lastBlock(&(ctx->ubictx), &conf, 256);
44         ubi256_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_MSG);
45 }
46 */
47 /*
48  * param ctx:       r24:r25
49  * param outsize_b: r22:r23
50  */
51 UBICTX0 = 2
52 UBICTX1 = 3
53 CONF0   = 4
54 CONF1   = 5
55 .global skein256_init
56 skein256_init:
57         push_range 2, 5
58         stack_alloc 64-22
59         adiw r30, 1
60         movw CONF0, r30
61         movw r26, r24
62         st X+, r22
63         st X+, r23
64         movw UBICTX0, r26
65         ldi r24, 'S'
66         st Z+, r24
67         ldi r24, 'H'
68         st Z+, r24
69         ldi r24, 'A'
70         st Z+, r24
71         ldi r24, '3'
72         st Z+, r24
73         ldi r24, 1
74         st Z+, r24
75         st Z+, r1
76         st Z+, r1
77         st Z+, r1
78         st Z+, r22
79         st Z+, r23
80         ldi 24, 22+10
81 1:  st Z+, r1
82         dec r24
83         brne 1b
84         /* call ubi256_init*/
85         sbiw r30, 32
86         movw r24, UBICTX0
87         movw r22, r30
88         ldi r20, 4
89         rcall ubi256_init
90         /* call ubi256_lastBlock*/
91         movw r24, UBICTX0
92         movw r22, CONF0
93         ldi r21, 1
94         clr r20
95         rcall ubi256_lastBlock
96         /* call ubi256_init*/
97         movw r24, UBICTX0
98         adiw r24, 16
99         movw r22, r24
100         movw r24, UBICTX0
101         ldi r20, 48
102         rcall ubi256_init
103         stack_free 64-22
104         pop_range 2, 5
105         ret
106
107 /******************************************************************************/
108 .global skein256_nextBlock
109 skein256_nextBlock:
110         adiw r24, 2
111         rjmp ubi256_nextBlock
112
113 /******************************************************************************/
114 .global skein256_lastBlock
115 skein256_lastBlock:
116         adiw r24, 2
117         rjmp ubi256_lastBlock
118
119 /******************************************************************************/
120 /*
121 void skein256_ctx2hash(void *dest, skein256_ctx_t *ctx){
122         ubi256_ctx_t uctx;
123         uint16_t outsize_b;
124
125         uint64_t counter=0;
126         uint8_t outbuffer[UBI256_BLOCKSIZE_B];
127         ubi256_init(&(ctx->ubictx), ctx->ubictx.g, UBI_TYPE_OUT);
128
129         outsize_b = ctx->outsize_b;
130         while(1){
131                 memcpy(&uctx, &(ctx->ubictx), sizeof(ubi256_ctx_t));
132                 ubi256_lastBlock(&uctx, &counter, 64);
133                 ubi256_ctx2hash(outbuffer, &uctx);
134                 if(outsize_b<=UBI256_BLOCKSIZE){
135                         memcpy(dest, outbuffer, (outsize_b+7)/8);
136                         break;
137                 }else{
138                         memcpy(dest, outbuffer, UBI256_BLOCKSIZE_B);
139                         dest = (uint8_t*)dest + UBI256_BLOCKSIZE_B;
140                         outsize_b -= UBI256_BLOCKSIZE;
141                         counter++;
142                 }
143         }
144 }
145 */
146 /*
147  * param dest: r24:r25
148  * param ctx:  r22:r23
149  */
150  OUTSIZE_B0 = 16
151  OUTSIZE_B1 = 17
152  UCTX0      = 14
153  UCTX1      = 15
154  UBICTX0    = 12
155  UBICTX1    = 13
156  DEST0      = 10
157  DEST1      = 11
158 .global skein256_ctx2hash
159 skein256_ctx2hash:
160         push_range 10, 17
161                               /*  48  ||  8      ||  32       */
162         stack_alloc_large 88  /* uctx || counter || outbuffer */
163         movw DEST0, r24
164         adiw r30, 1
165         movw UCTX0, r30
166         adiw r30, 48
167         st Z+, r1
168         st Z+, r1
169         st Z+, r1
170         st Z+, r1
171         st Z+, r1
172         st Z+, r1
173         st Z+, r1
174         st Z+, r1
175         movw r26, 22
176         ld OUTSIZE_B0, X+
177         ld OUTSIZE_B1, X+
178         movw UBICTX0, r26
179    /* call ubi256_init */
180         movw r24, UBICTX0
181         adiw r24, 16
182         movw r22, r24
183         movw r24, UBICTX0
184         ldi r20, 63
185         rcall ubi256_init
186
187    /* main loop */
188    /* copy ubictx in uctx*/
189 1:      movw r30, UCTX0
190         movw r26, UBICTX0
191         ldi r24, 48
192 2:      ld r25, X+
193         st Z+, r25
194         dec r24
195         brne 2b
196   /* call ubi256_lastBlock */
197     movw r24, UCTX0
198         adiw r24, 48
199         movw r22, r24
200         movw r24, UCTX0
201         clr r21
202         ldi r20, 64
203         rcall ubi256_lastBlock
204   /* copy uctx->g to outbuffer */
205         movw r26, UCTX0
206         adiw r26, 16
207         movw r30, UCTX0
208         adiw r30, 56
209         ldi r24, 32
210 2:      ld r25, X+
211     st Z+, r25
212         dec r24
213         brne 2b
214    /* compare outsize_b with 256*/
215         cpi OUTSIZE_B1, 2
216         brge 5f
217         cpi OUTSIZE_B1, 1
218         brlo 3f
219         tst OUTSIZE_B0
220         breq 3f
221 5:      /* copy outbuffer to dest */
222         movw r30, DEST0
223         movw r26, UCTX0
224         adiw r26, 56
225         ldi r24, 32
226 6:      ld r25, X+
227         st Z+, r25
228         dec r24
229         brne 6b
230         /* store new dest */
231         movw DEST0, r30 ;XXX r26
232         /* adjust counter and outsize_b*/
233         dec OUTSIZE_B1
234         movw r30, UCTX0
235         adiw r30, 48
236         ldi r24, 1
237         ld r25, Z
238         add r25, r24
239         st Z+, r25
240         ldi r24, 7
241 6:      ld r25, Z
242         adc r25, r1
243         st Z+, r25
244         dec r24
245         brne 6b
246         rjmp 1b
247 3:      /* last iteraton */
248         movw r24, OUTSIZE_B0
249         adiw r24, 7
250         lsr r25
251         ror r24
252         lsr r24
253         lsr r24
254         movw r30, DEST0
255         movw r26, UCTX0
256         adiw r26, 56
257         tst r24
258         breq 8f
259 7:      ld r25, X+
260         st Z+, r25
261         dec r24
262         brne 7b
263 8:
264         stack_free_large 88
265         pop_range 10, 17
266         ret
267
268 /******************************************************************************/
269 /*
270 void skein256(void *dest, uint16_t outlength_b, const void *msg, uint32_t length_b){
271         skein256_ctx_t ctx;
272         skein256_init(&ctx, outlength_b);
273         while(length_b>SKEIN256_BLOCKSIZE){
274                 skein256_nextBlock(&ctx, msg);
275                 msg = (uint8_t*)msg + SKEIN256_BLOCKSIZE_B;
276                 length_b -= SKEIN256_BLOCKSIZE;
277         }
278         skein256_lastBlock(&ctx, msg, length_b);
279         skein256_ctx2hash(dest, &ctx);
280 }
281 */
282 /*
283  * param dest:         r24:r25
284  * param outlength_b:  r22:r23
285  * param msg:          r20:r21
286  * param length_b:     r16:r19
287  */
288 LENGTH_B0 =  2
289 LENGTH_B1 =  3
290 LENGTH_B2 =  4
291 LENGTH_B3 =  5
292 DEST0     =  6
293 DEST1     =  7
294 MSG0      =  8
295 MSG1      =  9
296 CTX0      = 10
297 CTX1      = 11
298 .global skein256
299 skein256:
300         push_range 2, 11
301         stack_alloc 50
302         adiw r30, 1
303         movw CTX0, r30
304         movw DEST0, r24
305         movw MSG0, r20
306         movw LENGTH_B0, r16
307         movw LENGTH_B2, r18
308         /* call skein256_init */
309         movw r24, r30
310         rcall skein256_init
311 1:      tst LENGTH_B2
312         brne 4f
313         tst LENGTH_B3
314         brne 4f
315    /* call skein256_lastBlock */
316         movw r24, CTX0
317         movw r22, MSG0
318         movw r20, LENGTH_B0
319         rcall skein256_lastBlock
320    /* call skein256_ctx2hash */
321         movw r24, DEST0
322         movw r22, CTX0
323         rcall skein256_ctx2hash
324    /* return */
325         stack_free 50
326         pop_range 2, 11
327         ret
328
329 4: /* process preceeding blocks */
330         movw r24, CTX0
331         movw r22, MSG0
332         rcall skein256_nextBlock
333         movw r24, MSG0
334         adiw r24, 32
335         movw MSG0, r24
336         mov r24, LENGTH_B1
337         mov r25, LENGTH_B2
338         sbiw r24, 1
339         sbc LENGTH_B3, r1
340         mov LENGTH_B1, r24
341         mov LENGTH_B2, r25
342         rjmp 1b
343