]> git.cryptolib.org Git - avr-crypto-lib.git/blob - serpent-sboxes-fast.S
0adcc1349374749fc03cf6fc0bf3124802be10fc
[avr-crypto-lib.git] / serpent-sboxes-fast.S
1 /* serpent-sboxes-fast.S */
2 /*
3     This file is part of the Crypto-avr-lib/microcrypt-lib.
4     Copyright (C) 2008  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:        serpent-sboxes-fast.S
22  * Author:      Daniel Otte
23  * Date:        2008-08-07
24  * License:     GPLv3 or later
25  * Description: Implementation of the serpent sbox function.
26  * 
27  */
28  
29 #include <avr/io.h>
30
31 /*******************************************************************************
32 *  MACRO SECTION                                                               *
33 *******************************************************************************/
34
35 .macro push_ p1:req, p2:vararg
36         push \p1
37 .ifnb \p2       
38         push_ \p2
39 .endif
40 .endm
41
42 .macro pop_ p1:req, p2:vararg
43         pop \p1
44 .ifnb \p2       
45         pop_ \p2
46 .endif
47 .endm
48
49 .macro push_range from:req, to:req
50         push \from
51 .if     \to-\from
52         push_range "(\from+1)",\to
53 .endif          
54 .endm
55
56 .macro pop_range from:req, to:req
57         pop \to
58 .if     \to-\from
59         pop_range \from,"(\to-1)"       
60 .endif
61 .endm
62
63 .macro stack_alloc size:req, reg1=r30, reg2=r31
64         in r0, _SFR_IO_ADDR(SREG)
65         cli
66         in \reg1, _SFR_IO_ADDR(SPL)
67         in \reg2, _SFR_IO_ADDR(SPH)
68         sbiw \reg1, \size 
69         out _SFR_IO_ADDR(SPH), \reg2
70         out _SFR_IO_ADDR(SPL), \reg1
71         out _SFR_IO_ADDR(SREG), r0
72 .endm
73
74 .macro stack_free size:req, reg1=r30, reg2=r31
75         in r0, _SFR_IO_ADDR(SREG)
76         cli
77         in \reg1, _SFR_IO_ADDR(SPL)
78         in \reg2, _SFR_IO_ADDR(SPH)
79         adiw \reg1, \size 
80         out _SFR_IO_ADDR(SPH), \reg2
81         out _SFR_IO_ADDR(SPL), \reg1
82         out _SFR_IO_ADDR(SREG), r0
83 .endm
84
85 /*******************************************************************************
86 * END of MACRO SECTION                                                         *
87 *******************************************************************************/
88
89 serpent_sbox_fast:
90  .byte 0x33, 0x88, 0xFF, 0x11, 0xAA, 0x66, 0x55, 0xBB 
91  .byte 0xEE, 0xDD, 0x44, 0x22, 0x77, 0x00, 0x99, 0xCC
92  .byte 0xFF, 0xCC, 0x22, 0x77, 0x99, 0x00, 0x55, 0xAA
93  .byte 0x11, 0xBB, 0xEE, 0x88, 0x66, 0xDD, 0x33, 0x44 
94  .byte 0x88, 0x66, 0x77, 0x99, 0x33, 0xCC, 0xAA, 0xFF 
95  .byte 0xDD, 0x11, 0xEE, 0x44, 0x00, 0xBB, 0x55, 0x22
96  .byte 0x00, 0xFF, 0xBB, 0x88, 0xCC, 0x99, 0x66, 0x33 
97  .byte 0xDD, 0x11, 0x22, 0x44, 0xAA, 0x77, 0x55, 0xEE
98  .byte 0x11, 0xFF, 0x88, 0x33, 0xCC, 0x00, 0xBB, 0x66 
99  .byte 0x22, 0x55, 0x44, 0xAA, 0x99, 0xEE, 0x77, 0xDD
100  .byte 0xFF, 0x55, 0x22, 0xBB, 0x44, 0xAA, 0x99, 0xCC 
101  .byte 0x00, 0x33, 0xEE, 0x88, 0xDD, 0x66, 0x77, 0x11
102  .byte 0x77, 0x22, 0xCC, 0x55, 0x88, 0x44, 0x66, 0xBB 
103  .byte 0xEE, 0x99, 0x11, 0xFF, 0xDD, 0x33, 0xAA, 0x00
104  .byte 0x11, 0xDD, 0xFF, 0x00, 0xEE, 0x88, 0x22, 0xBB 
105  .byte 0x77, 0x44, 0xCC, 0xAA, 0x99, 0x33, 0x55, 0x66
106
107 serpent_sbox_inv_fast:
108  .byte 0xDD, 0x33, 0xBB, 0x00, 0xAA, 0x66, 0x55, 0xCC 
109  .byte 0x11, 0xEE, 0x44, 0x77, 0xFF, 0x99, 0x88, 0x22
110  .byte 0x55, 0x88, 0x22, 0xEE, 0xFF, 0x66, 0xCC, 0x33 
111  .byte 0xBB, 0x44, 0x77, 0x99, 0x11, 0xDD, 0xAA, 0x00
112  .byte 0xCC, 0x99, 0xFF, 0x44, 0xBB, 0xEE, 0x11, 0x22 
113  .byte 0x00, 0x33, 0x66, 0xDD, 0x55, 0x88, 0xAA, 0x77
114  .byte 0x00, 0x99, 0xAA, 0x77, 0xBB, 0xEE, 0x66, 0xDD 
115  .byte 0x33, 0x55, 0xCC, 0x22, 0x44, 0x88, 0xFF, 0x11
116  .byte 0x55, 0x00, 0x88, 0x33, 0xAA, 0x99, 0x77, 0xEE 
117  .byte 0x22, 0xCC, 0xBB, 0x66, 0x44, 0xFF, 0xDD, 0x11
118  .byte 0x88, 0xFF, 0x22, 0x99, 0x44, 0x11, 0xDD, 0xEE 
119  .byte 0xBB, 0x66, 0x55, 0x33, 0x77, 0xCC, 0xAA, 0x00
120  .byte 0xFF, 0xAA, 0x11, 0xDD, 0x55, 0x33, 0x66, 0x00 
121  .byte 0x44, 0x99, 0xEE, 0x77, 0x22, 0xCC, 0x88, 0xBB
122  .byte 0x33, 0x00, 0x66, 0xDD, 0x99, 0xEE, 0xFF, 0x88 
123  .byte 0x55, 0xCC, 0xBB, 0x77, 0xAA, 0x11, 0x44, 0x22
124                   
125  
126 /*
127  * void ip(uint32_t *i, uint8_t *o){
128  */
129 /* 
130  * param i is given in r24:r25
131  * parma o is given in r22:r23
132  */
133 .global serpent_ip
134 serpent_ip:
135         push_range 2, 17        
136         movw r26, r24
137         ldi r24, 16
138         clr r31
139         ldi r30, 2
140 1:
141         ld r25, X+
142         st Z+, r25
143         dec r24
144         brne 1b
145         /* now the whole input is loaded in r2-r18 */
146         movw r26, r22
147         ldi r21, 4
148 4:
149         ldi r20, 8      
150 2:      
151         lsr r2
152         ror r19
153         lsr r6
154         ror 19
155         lsr r10
156         ror r19
157         lsr r14
158         ror 19
159         sbrc r20, 0
160         st X+, r19
161         dec r20
162         brne 2b
163         
164         ldi r20, 15
165         ldi r30, 2
166 3:
167         ldd r19, Z+1
168         st Z+, r19
169         dec r20
170         brne 3b
171         
172         dec r21
173         brne 4b
174         pop_range 2, 17 
175         ret
176
177 /*
178  * void serpent_fp(uint32_t *i, uint8_t *o){
179  */
180 /* 
181  * param i is given in r24:r25
182  * parma o is given in r22:r23
183  */
184 .global serpent_fp
185 serpent_fp:
186         movw r26, r24
187         movw r30, r22
188         ldi r18, 4
189 1:      
190         ldi r19, 8 
191 2:
192         sbrs r19, 0
193         ld r24, X+
194 3:
195         lsr r24
196         ror r20
197         lsr r24
198         ror r21
199         lsr r24
200         ror r22
201         lsr r24
202         ror r23
203         dec r19
204         brne 2b
205         
206         st Z+, r20
207         std Z+3, r21
208         std Z+7, r22
209         std Z+11, r23
210         
211         dec r18
212         brne 1b         
213         ret
214         
215
216 /*
217  * void inv_sbox128(void * w, uint8_t box)
218  */
219 .global inv_sbox128 
220 inv_sbox128:
221         andi r22, 0x07
222         ori  r22, 0x08
223         rjmp sbox128x_fast
224  
225 /*      
226  * void sbox128(void * w, uint8_t box);
227  */
228 /*
229  * param w   is passed in r24:r25
230  * param box is passed in r22
231  */
232 .global sbox128 
233 sbox128:
234         andi r22, 0x07
235  
236 sbox128x_fast:
237         stack_alloc 16
238         adiw r30, 1
239         push_ r24, r25, r22, r30, r31
240         movw r22, r30   /* Z points to the stack buffer */
241         rcall serpent_ip
242         pop_ r27, r26, r22
243         ldi r25, hi8(serpent_sbox_fast)
244         ldi r24, lo8(serpent_sbox_fast)
245         swap r22 /* r22 *= 16 */
246         add r24, r22
247         adc r25, r1
248         /* now we have X pointing to the buffer and (r24:r25) pointing to the SBox */
249         ldi r22, 16
250 1:      
251         movw r30, r24
252         ld r18, X
253         mov r20, r18
254         andi r18, 0x0f
255         add r30, r18
256         adc r31, r1
257         lpm r19, Z
258 2:      
259         swap r20
260         andi r20, 0x0f
261         movw r30, r24
262         add r30, r20
263         adc r31, r1
264         lpm r21, Z
265 3:      
266         andi r19, 0x0F
267         andi r21, 0xF0
268         or r19, r21
269         st X+, r19
270         dec r22
271         brne 1b
272         
273         pop_ r23, r22
274         movw r24, r26
275         sbiw r24, 16
276
277         rcall serpent_fp
278         
279         stack_free 16   
280         ret
281
282
283
284
285
286
287  
288
289