]> git.cryptolib.org Git - avr-crypto-lib.git/blob - serpent-sboxes-small.S
3259240338a1f9efbc96d84dd017571b26220443
[avr-crypto-lib.git] / serpent-sboxes-small.S
1 /* serpent_sboxes.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.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 serpent_sbox:
89  .byte 0x83, 0x1F, 0x6A, 0xB5, 0xDE, 0x24, 0x07, 0xC9
90  .byte 0xCF, 0x72, 0x09, 0xA5, 0xB1, 0x8E, 0xD6, 0x43 
91  .byte 0x68, 0x97, 0xC3, 0xFA, 0x1D, 0x4E, 0xB0, 0x25
92  .byte 0xF0, 0x8B, 0x9C, 0x36, 0x1D, 0x42, 0x7A, 0xE5
93  .byte 0xF1, 0x38, 0x0C, 0x6B, 0x52, 0xA4, 0xE9, 0xD7
94  .byte 0x5F, 0xB2, 0xA4, 0xC9, 0x30, 0x8E, 0x6D, 0x17
95  .byte 0x27, 0x5C, 0x48, 0xB6, 0x9E, 0xF1, 0x3D, 0x0A
96  .byte 0xD1, 0x0F, 0x8E, 0xB2, 0x47, 0xAC, 0x39, 0x65
97
98 serpent_sbox_inv:
99  .byte 0x3D, 0x0B, 0x6A, 0xC5, 0xE1, 0x74, 0x9F, 0x28
100  .byte 0x85, 0xE2, 0x6F, 0x3C, 0x4B, 0x97, 0xD1, 0x0A
101  .byte 0x9C, 0x4F, 0xEB, 0x21, 0x30, 0xD6, 0x85, 0x7A
102  .byte 0x90, 0x7A, 0xEB, 0xD6, 0x53, 0x2C, 0x84, 0x1F
103  .byte 0x05, 0x38, 0x9A, 0xE7, 0xC2, 0x6B, 0xF4, 0x1D
104  .byte 0xF8, 0x92, 0x14, 0xED, 0x6B, 0x35, 0xC7, 0x0A
105  .byte 0xAF, 0xD1, 0x35, 0x06, 0x94, 0x7E, 0xC2, 0xB8
106  .byte 0x03, 0xD6, 0xE9, 0x8F, 0xC5, 0x7B, 0x1A, 0x24                  
107  
108 /*
109  * void ip(uint32_t *i, uint8_t *o){
110  */
111 /* 
112  * param i is given in r24:r25
113  * parma o is given in r22:r23
114  */
115 .global serpent_ip
116 serpent_ip:
117         push_range 2, 17        
118         movw r26, r24
119         ldi r24, 16
120         clr r31
121         ldi r30, 2
122 1:
123         ld r25, X+
124         st Z+, r25
125         dec r24
126         brne 1b
127         /* now the whole input is loaded in r2-r18 */
128         movw r26, r22
129         ldi r21, 4
130 4:
131         ldi r20, 8      
132 2:      
133         lsr r2
134         ror r19
135         lsr r6
136         ror 19
137         lsr r10
138         ror r19
139         lsr r14
140         ror 19
141         sbrc r20, 0
142         st X+, r19
143         dec r20
144         brne 2b
145         
146         ldi r20, 15
147         ldi r30, 2
148 3:
149         ldd r19, Z+1
150         st Z+, r19
151         dec r20
152         brne 3b
153         
154         dec r21
155         brne 4b
156         pop_range 2, 17 
157         ret
158
159 /*
160  * void serpent_fp(uint32_t *i, uint8_t *o){
161  */
162 /* 
163  * param i is given in r24:r25
164  * parma o is given in r22:r23
165  */
166 .global serpent_fp
167 serpent_fp:
168         movw r26, r24
169         movw r30, r22
170         ldi r18, 4
171 1:      
172         ldi r19, 8 
173 2:
174         sbrs r19, 0
175         ld r24, X+
176 3:
177         lsr r24
178         ror r20
179         lsr r24
180         ror r21
181         lsr r24
182         ror r22
183         lsr r24
184         ror r23
185         dec r19
186         brne 2b
187         
188         st Z+, r20
189         std Z+3, r21
190         std Z+7, r22
191         std Z+11, r23
192         
193         dec r18
194         brne 1b 
195         
196         ret
197 /*
198  * void inv_sbox128(void * w, uint8_t box)
199  */
200 .global inv_sbox128 
201 inv_sbox128:
202         andi r22, 0x07
203         ori  r22, 0x08
204         rjmp sbox128x
205  
206 /*      
207  * void sbox128(void * w, uint8_t box);
208  */
209 /*
210  * param w   is passed in r24:r25
211  * param box is passed in r22
212  */
213 .global sbox128 
214 sbox128:
215         andi r22, 0x07
216
217 /*      
218  * void sbox128x(void * w, uint8_t box);
219  */
220 /*
221  * param w   is passed in r24:r25
222  * param box is passed in r22
223  */
224  
225 .global sbox128x
226 sbox128x:
227         stack_alloc 16
228         adiw r30, 1
229         push_ r24, r25, r22, r30, r31
230         movw r22, r30   /* Z points to the stack buffer */
231         rcall serpent_ip
232         pop_ r27, r26, r22
233         ldi r25, hi8(serpent_sbox)
234         ldi r24, lo8(serpent_sbox)
235         swap r22
236         lsr  r22 /* r22 *= 8 */
237         add r24, r22
238         adc r25, r1
239         /* now we have X pointing to the buffer and (r24:r25) pointing to the SBox */
240         ldi r22, 16
241 1:      
242         movw r30, r24
243         ld r18, X
244         mov r20, r18
245         andi r18, 0x0f
246         bst r18, 0
247         lsr r18
248         add r30, r18
249         adc r31, r1
250         lpm r19, Z
251         brtc 2f
252         swap r19
253 2:      
254         swap r20
255         andi r20, 0x0f
256         bst r20, 0
257         lsr r20
258         movw r30, r24
259         add r30, r20
260         adc r31, r1
261         lpm r21, Z
262         brts 3f
263         swap r21
264 3:      
265         andi r19, 0x0F
266         andi r21, 0xF0
267         or r19, r21
268         st X+, r19
269         dec r22
270         brne 1b
271         
272         pop_ r23, r22
273         movw r24, r26
274         sbiw r24, 16
275
276         rcall serpent_fp
277         
278         stack_free 16   
279         ret
280  
281
282
283
284  
285
286