]> git.cryptolib.org Git - avr-crypto-lib.git/blob - bigint/bigint_asm.S
some bigint stuff in ASM
[avr-crypto-lib.git] / bigint / bigint_asm.S
1 /* bigint_asm.S */
2 /*
3     This file is part of the ARM-Crypto-Lib.
4     Copyright (C) 2006-2010 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 #include "avr-asm-macros.S"
21 #include "bigint_adjust.S"
22 #include "bigint_add_u.S"
23
24
25 /******************************************************************************/
26 /*
27 void bigint_add_scale_u(bigint_t* dest, const bigint_t* a, uint16_t scale){
28         uint16_t i,j=0;
29         uint16_t t=0;
30         if(scale>dest->length_B)
31                 memset(dest->wordv+dest->length_B, 0, scale-dest->length_B);
32         for(i=scale; i<a->length_B+scale; ++i,++j){
33                 t = a->wordv[j] + t;
34                 if(dest->length_B>i){
35                         t += dest->wordv[i];
36                 }
37                 dest->wordv[i] = (uint8_t)t;
38                 t>>=8;
39         }
40         while(t){
41                 if(dest->length_B>i){
42                         t = dest->wordv[i] + t;
43                 }
44                 dest->wordv[i] = (uint8_t)t;
45                 t>>=8;
46                 ++i;
47         }
48         if(dest->length_B < i){
49                 dest->length_B = i;
50         }
51         bigint_adjust(dest);
52 }
53 */
54
55 DST_SIZE_0 = 22
56 DST_SIZE_1 = 23
57 SRC_SIZE_0 = 20
58 SRC_SIZE_1 = 23
59 SCALE_0    = 18
60 SCALE_1    = 19
61 DST_CTX_0  =  6
62 DST_CTX_1  =  7
63 SRC_CTX_0  =  8
64 SRC_CTX_1  =  9
65 TMP_0      = 10
66 TMP_1      = 11
67
68 .global bigint_add_scale_u
69 #if 0
70 bigint_add_scale_u:
71         push_range 6, 11
72         movw r30, r24 /* dest ptr */
73         movw r26, r22 /* src ptr */
74         movw r24, r20 /* scale */
75         movw DST_CTX_0, r30
76         movw SRC_CTX_0, r26
77         movw SCALE_0, r24
78         /* pad dst with zeros if scale > dst_length */
79         ld DST_SIZE_0, Z+
80         ld DST_SIZE_1, Z+
81         sub r24, DST_SIZE_0
82         sbc r25, DST_SIZE_1
83         ldd TMP_0, Z+1 /* load tmp with DST_WORDV */
84         ldd TMP_1, Z+2
85         movw r30, TMP_0
86         brmi 20f /* branch if DST_SIZE > scale */
87         add r30, DST_SIZE_0
88         adc r31, DST_SIZE_1
89 10:
90         sbiw r24, 1
91         brmi 25f
92         st Z+, r1
93         rjmp 10b
94 20:
95         add r30, r20 /* add scale to DST_WORDV */
96         adc r31, r21
97         /* add src to dest until one of the two ends */
98 25:
99         ld SRC_SIZE_0, X+
100         ld SRC_SIZE_1, X+
101         adiw r26, 1
102         ld TMP_0, X+ /* load tmp with SRC_WORDV */
103         ld TMP_1, X
104         movw r26, TMP_0
105         movw r24, SRC_SIZE_0
106         add r24, SCALE_0
107         adc r25, SCALE_1
108         clt
109         cp  r24, DST_SIZE_0
110         cpc r25, DST_SIZE_1
111         brlo 30f
112         set
113         movw r24, DST_SIZE_0
114 30:
115         adiw r24, 0
116         breq 35f
117         inc r25
118         clc
119 31:
120         ld TMP_0, X+
121         ld TMP_1, Z
122         adc TMP_1, TMP_0
123         st Z+, TMP_1
124         dec r24
125         brne 31b
126         dec r25
127         brne 31b
128 35:
129         rol TMP_1
130         brts 40f
131         /* dst is longer than src+scale */
132         ror TMP_1
133 38:
134         ld TMP_0, Z
135         adc TMP_0, r1
136         st Z+, TMP_0
137         brcs 38b
138         rjmp 90f
139 40:
140         /* dst is shorter than src+scale */
141         movw r24, SRC_SIZE_0
142         sub r24, DST_SIZE_0
143         sbc r25, DST_SIZE_1
144         add r24, SCALE_0
145         adc r25, SCALE_1
146         adiw r24, 0
147         breq 90f
148         inc r25
149         ror TMP_1
150 45:
151         ld TMP_0, X+
152         adc TMP_0, r1
153         st Z+, TMP_0
154         dec r24
155         brne 45b
156         dec r25
157         brne 45b
158
159 90:
160         movw r24, DST_CTX_0
161         pop_range 6, 11
162         rjmp bigint_adjust
163
164 #endif
165
166 /******************************************************************************/
167 /******************************************************************************/
168 /******************************************************************************/
169
170 DST_LEN_0 = 22
171 DST_LEN_1 = 23
172 SRC_LEN_0 = 20
173 SRC_LEN_1 = 21
174 SCALE_0   = 18
175 SCALE_1   = 19
176 DST_CTX_0 =  6
177 DST_CTX_1 =  7
178 SRC_CTX_0 =  8
179 SRC_CTX_1 =  9
180 TMP_0     = 10
181 TMP_1     = 11
182
183 bigint_add_scale_u:
184         push_range 6, 11
185         movw r30, r24 /* dest ptr */
186         movw r26, r22 /* src ptr */
187         movw r24, r20 /* scale */
188         movw DST_CTX_0, r30
189         movw SRC_CTX_0, r26
190         movw SCALE_0, r24
191
192         /* pad dest with zeros to length of SRC_LENGTH + scale */
193         ld SRC_LEN_0, X+
194         ld SRC_LEN_1, X+
195         adiw r26, 1
196         ld TMP_0, X+
197         ld TMP_1, X+
198         movw r26, TMP_0 /* move SRC_WORDV to X */
199         ldd DST_LEN_0, Z+0
200         ldd DST_LEN_1, Z+1
201     ldd TMP_0, Z+3
202     ldd TMP_1, Z+4
203     movw r30, TMP_0 /* move DEST_WORDV to Z */
204         movw TMP_0, SCALE_0
205         sub TMP_0, DST_LEN_0
206         sbc TMP_1, DST_LEN_1
207         movw r24, TMP_0
208         brmi 40f /* no padding needed since DST_LEN > scale */
209         add r30, DST_LEN_0 /* add DST_LEN to Z (DEST_WORDV)*/
210         adc r31, DST_LEN_1
211         /* pad and copy src in front of dest */
212 10: /* padding loop */
213         sbiw r24, 1
214         brmi 11f
215         st Z+, r1
216         rjmp 10b
217 11:
218         /* start of copy */
219
220         movw r24, SRC_LEN_0
221
222 12: /* copy loop */
223         sbiw r24, 1
224         brmi 13f
225         ld TMP_0, X+
226         st Z+, TMP_0
227         rjmp 12b
228 13:
229         movw TMP_0, SCALE_0
230         add TMP_0, SRC_LEN_0
231         adc TMP_1, SRC_LEN_1
232         movw r30, DST_CTX_0
233         std Z+0, TMP_0
234         std Z+1, TMP_1
235         movw r24, r30
236 99:
237         pop_range 6, 11
238         rjmp bigint_adjust
239 40:
240     /* TODO */
241     /* Z points at DST_WORDV */
242     /* X points at SRC_WORDV */
243     /* r24:r25 contains scale - DST_LEN (negativ) */
244     /* set T bit if DST_LEN > SCR_LEN + scale */
245     clt
246     add r30, SCALE_0
247     adc r31, SCALE_1
248     add TMP_0, SRC_LEN_0
249     adc TMP_1, SRC_LEN_1
250         brpl 41f
251         set
252         /* DST_LEN > SRC_LEN + scale && DST_LEN > scale */
253         /*
254                +-------+-------+ SRC + scale
255            +------+------------+ DST
256         */
257         movw r24, SRC_LEN_0
258         rjmp 44f
259 41:
260         /* DST_LEN <= SRC_LEN + scale && DST_LEN > scale */
261         /*
262                +-------+-------+ SRC + scale
263                   +------------+ DST
264         */
265         com r24 /* negate r24:r25 */
266         com r25
267         adiw r24, 1
268 44:
269         clc
270 45:
271         dec r24
272         brpl 46f
273         dec r25
274         brmi 50f
275 46:     ld TMP_0, X+
276         ld TMP_1, Z
277         adc TMP_0, TMP_1
278         st Z+, TMP_0
279         rjmp 45b
280
281 50:
282     /* do the overhaning part */
283     rol r1
284     movw r24, r30
285     movw r30, DST_CTX_0
286     ldd TMP_0, Z+3
287     ldd TMP_1, Z+4
288     movw r30, TMP_0
289     add r30, DST_LEN_0
290     adc r31, DST_LEN_1
291     adiw r30, 1
292     st Z, r1
293     movw r30, r24
294     ror r1
295         brtc 60f
296 51:     brcc 53f
297 52:     ld TMP_0, Z
298         adc TMP_0, r1
299         st Z+, TMP_0
300         brcs 52b
301 53:
302     /* TODO */
303     movw r24, r30
304     movw r30, DST_CTX_0
305     ldd TMP_0, Z+3
306     ldd TMP_1, Z+4
307     sub r24, TMP_0
308     sbc r25, TMP_1
309     std Z+0, r24
310     std Z+1, r25
311     movw r24, r30
312     rjmp 99b
313
314 60: rol r1 /* backup carry */
315         movw r24, SRC_LEN_0
316     add r24, SCALE_0
317     adc r25, SCALE_1
318     sub r24, DST_LEN_0
319     sbc r25, DST_LEN_1
320     ror r1 /* restore carry */
321
322 61: dec r24
323     brpl 62f
324     dec r25
325     brmi 63f
326 62: ld TMP_0, X+
327     adc TMP_0, r1
328     st Z+, TMP_0
329     rjmp 61b
330 63:
331         brcc 53b
332         ldi r24, 1
333         st Z+, r24
334         rjmp 53b