]> git.cryptolib.org Git - avr-crypto-lib.git/blob - bigint/bigint_asm.S
1942fa33e7ff0631d027ba7cf3df9faad8acf2e5
[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
70
71 /******************************************************************************/
72 /******************************************************************************/
73 /******************************************************************************/
74
75 DST_LEN_0 = 22
76 DST_LEN_1 = 23
77 SRC_LEN_0 = 20
78 SRC_LEN_1 = 21
79 SCALE_0   = 18
80 SCALE_1   = 19
81 DST_CTX_0 =  8
82 DST_CTX_1 =  9
83 TMP_0     = 10
84 TMP_1     = 11
85
86 bigint_add_scale_u:
87         movw r30, r24 /* dest ptr */
88         movw r26, r22 /* src ptr */
89         movw r24, r20 /* scale */
90         /* check if scale is zero */
91         movw SCALE_0, r24
92         adiw r24, 0
93         brne 10f
94         movw r24, r30
95         movw r20, r30
96         rjmp bigint_add_u
97 10:     /* check if src is zero */
98         ld r24, X+
99         ld r25, X+
100         adiw r24, 0
101         brne 10f
102         ret
103 10:
104         movw SRC_LEN_0, r24
105         push_range 8, 11
106         movw DST_CTX_0, r30
107
108         /* pad dest with zeros to length of SRC_LENGTH + scale */
109         adiw r26, 1
110         ld TMP_0, X+
111         ld TMP_1, X+
112         movw r26, TMP_0 /* move SRC_WORDV to X */
113         ldd DST_LEN_0, Z+0
114         ldd DST_LEN_1, Z+1
115     ldd TMP_0, Z+3
116     ldd TMP_1, Z+4
117     movw r30, TMP_0 /* move DEST_WORDV to Z */
118         movw TMP_0, SCALE_0
119         sub TMP_0, DST_LEN_0
120         sbc TMP_1, DST_LEN_1
121         movw r24, TMP_0
122         brmi 40f /* no padding needed since DST_LEN > scale */
123         add r30, DST_LEN_0 /* add DST_LEN to Z (DEST_WORDV)*/
124         adc r31, DST_LEN_1
125         /* pad and copy src in front of dest */
126 10: /* padding loop */
127         sbiw r24, 1
128         brmi 11f
129         st Z+, r1
130         rjmp 10b
131 11:
132         /* start of copy */
133         movw r24, SRC_LEN_0
134
135 12: /* copy loop */
136         sbiw r24, 1
137         brmi 13f
138         ld TMP_0, X+
139         st Z+, TMP_0
140         rjmp 12b
141 13:
142         movw TMP_0, SCALE_0
143         add TMP_0, SRC_LEN_0
144         adc TMP_1, SRC_LEN_1
145         movw r30, DST_CTX_0
146         std Z+0, TMP_0
147         std Z+1, TMP_1
148         movw r24, r30
149 99:
150         pop_range 8, 11
151         rjmp bigint_adjust
152 40:
153     /* Z points at DST_WORDV */
154     /* X points at SRC_WORDV */
155     /* r24:r25 and TMP contain scale - DST_LEN (negativ) */
156     /* set T bit if DST_LEN > SCR_LEN + scale */
157     clt
158     add r30, SCALE_0
159     adc r31, SCALE_1
160     add TMP_0, SRC_LEN_0
161     adc TMP_1, SRC_LEN_1
162         brpl 41f
163         set
164         /* DST_LEN > SRC_LEN + scale && DST_LEN > scale */
165         /*
166                +-------+-------+ SRC + scale
167            +------+------------+ DST
168         */
169         movw r24, SRC_LEN_0
170         rjmp 44f
171 41:
172         /* DST_LEN <= SRC_LEN + scale && DST_LEN > scale */
173         /*
174                +-------+-------+ SRC + scale
175                   +------------+ DST
176         */
177         com r24 /* negate r24:r25 ==> DST_LEN - scale */
178         com r25
179         adiw r24, 1
180         breq 50f
181 44:
182         inc r25
183         clc
184 45:
185 46:     ld TMP_0, X+
186         ld TMP_1, Z
187         adc TMP_0, TMP_1
188         st Z+, TMP_0
189         dec r24
190         brne 46b
191         dec r25
192         brne 46b
193
194 50: ;st Z, r1
195         brtc 60f
196 51:     brcc 53f
197 52:     ld TMP_0, Z
198         adc TMP_0, r1
199         st Z+, TMP_0
200         brcs 52b
201 53:
202     /* epilogue */
203     movw r24, r30
204     movw r30, DST_CTX_0
205     ldd TMP_0, Z+3
206     ldd TMP_1, Z+4
207     sub r24, TMP_0
208     sbc r25, TMP_1
209     cp  r24, DST_LEN_0
210     cpc r25, DST_LEN_1
211     brmi 54f
212     std Z+0, r24
213     std Z+1, r25
214 54: movw r24, r30
215     rjmp 99b
216
217 60: st Z, r1
218         rol r1 /* backup carry */
219         movw r24, SRC_LEN_0
220     add r24, SCALE_0
221     adc r25, SCALE_1
222     sub r24, DST_LEN_0
223     sbc r25, DST_LEN_1
224
225         adiw r24, 0
226         breq 63f
227         inc r25
228     ror r1 /* restore carry */
229
230 61:
231 62: ld TMP_0, X+
232     adc TMP_0, r1
233     st Z+, TMP_0
234     dec r24
235     brne 62b
236     dec r25
237     brne 62b
238 63:
239         brcc 53b
240         ldi r24, 1
241         st Z+, r24
242         rjmp 53b