]> git.cryptolib.org Git - avr-crypto-lib.git/blob - keccak/keccak-asm.S
[keccak-asm] rho & pi in asm
[avr-crypto-lib.git] / keccak / keccak-asm.S
1 /* keccac-asm.S */
2 /*
3     This file is part of the AVR-Crypto-Lib.
4     Copyright (C) 2012  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  * \file     keccak-asm.S
21  * \email    daniel.otte@rub.de
22  * \author   Daniel Otte
23  * \date     2012-12-16
24  * \license  GPLv3 or later
25  *
26  */
27
28 .nolist
29 #include "avr-asm-macros.S"
30 .list
31
32 .equ __zero_reg__, 1
33
34 .global rho_pi_idx_table
35 rho_pi_idx_table:
36         .irp i, 0, 1, 2, 3, 4
37                 .irp j, 0, 1, 2, 3, 4
38                         .byte (((2 * \j + 3 * \i) % 5) * 5 + \i) * 8
39                 .endr
40         .endr
41
42 .align 2
43 /*
44         void keccak_theta (uint64_t *a, uint64_t *b){
45         // uint64_t b[5][5];
46                 for(i = 0; i < 5; ++i){
47                         b[i][0] = a[0][i] ^ a[1][i] ^ a[2][i] ^ a[3][i] ^ a[4][i];
48                 }
49         }
50 */
51
52 /*********************************************
53  * theta_2a
54  *********************************************
55         input:
56                 r24:r25 = a ; uint64_t a[5][5]
57                 X = b       ; uint64_t *b
58         output:
59                 a[0..4][0] ^= b
60                 r20 = 0
61                 r21 = XX
62                 r22 = XX
63                 r24:r25 += 8
64                 X += 8
65                 Z = r24:r25 + 7 + 4 * 40
66 */
67 theta_2a:
68         ldi r20, 8
69 10:
70         movw ZL, r24
71         ld  r21, X+
72         .irp r, 0, 1, 2, 3, 4
73                 ld  r22, Z
74                 eor r22, r21
75                 st  Z, r22
76         .if \r != 4
77                 adiw ZL, 40
78         .endif
79         .endr
80         adiw r24, 1
81         dec r20
82         brne 10b
83         ret
84
85 /*********************************************
86  * theta_2b
87  *********************************************
88         input:
89                 r24:r25 = a+1 ; uint64_t a[5][5]
90                 X = b       ; uint64_t *b
91         output:
92                 a[0..4][0] ^= rol(b,1)
93                 r19 = XX
94                 r20 = 0
95                 r21 = XX
96                 r22 = XX
97                 r24:r25 += 8
98                 X += 8
99                 Z = r24:r25 + 7 + 4 * 40
100 */
101 theta_2b:
102         ldi r20, 7
103         ld r19, X+
104         lsl r19
105         rol __zero_reg__
106 10:
107         movw ZL, r24
108         ld  r21, X+
109         ror __zero_reg__
110         rol r21
111         rol __zero_reg__
112         .irp r, 0, 1, 2, 3, 4
113                 ld  r22, Z
114                 eor r22, r21
115                 st  Z, r22
116         .if \r != 4
117                 adiw ZL, 40
118         .endif
119         .endr
120         adiw r24, 1
121         dec r20
122         brne 10b
123         add r19, __zero_reg__
124         sbiw r24, 8
125         movw ZL, r24
126         .irp r, 0, 1, 2, 3, 4
127                 ld  r22, Z
128                 eor r22, r19
129                 st  Z, r22
130         .if \r != 4
131                 adiw ZL, 40
132         .endif
133         .endr
134         adiw r24, 9
135         clr __zero_reg__
136         ret
137
138
139 .global keccak_theta
140 keccak_theta:
141         push_range 2, 8
142         push r16
143         push_range 28, 29
144
145         movw r30, r24 ; Z = a
146         movw r26, r22 ; X = b
147         push_range 22, 25
148
149         ldi r19, 5
150 10:
151         ldi r20, 8
152 20:
153         ld  r22, Z
154         adiw ZL, 40
155         ld  r21, Z
156         eor r22, r21
157         adiw ZL, 40
158         ld  r21, Z
159         eor r22, r21
160         adiw ZL, 40
161         ld  r21, Z
162         eor r22, r21
163         adiw ZL, 40
164         ld  r21, Z
165         eor r22, r21
166         adiw r24, 1
167         movw r30, r24
168         st X+, r22
169         dec r20
170         brne 20b
171
172         adiw XL, 8 * 4
173         dec r19
174         brne 10b
175 /*
176         for(i = 0; i < 5; ++i){
177                 for(j = 0; j < 5; ++j){
178                         a[j][i] ^= b[(4 + i) % 5][0];
179                 }
180         }
181
182 */
183 /* a[0..4][0]{0..7} ^= b[4][0]{0..7} */
184         sbiw XL, 5 * 8
185         sbiw r24, 40
186         rcall theta_2a
187 /* a[0..4][1]{0..7} ^= b[0][0]{0..7} */
188         subi XL, lo8(4 * 5 * 8 + 8)
189         sbci XH, hi8(4 * 5 * 8 + 8)
190         rcall theta_2a
191 /* a[0..4][2]{0..7} ^= b[1][0]{0..7} */
192         adiw XL, 4 * 8
193         rcall theta_2a
194 /* a[0..4][3]{0..7} ^= b[2][0]{0..7} */
195         adiw XL, 4 * 8
196         rcall theta_2a
197 /* a[0..4][4]{0..7} ^= b[3][0]{0..7} */
198         adiw XL, 4 * 8
199         rcall theta_2a
200 /*
201         for(i = 0; i < 5; ++i){
202         for(j = 0; j < 5; ++j){
203             a[j][i] ^= rotate64_1bit_left(b[(i + 1) % 5][0]);
204         }
205     }
206 */
207 /* a[0..4][0]{0..7} ^= rol(b[1][0]{0..7}) */
208         subi r24, lo8(5 * 8 - 1)
209         sbci r25, hi8(5 * 8 - 1)
210         subi XL, lo8(2 * 5 * 8 + 8)
211         sbci XH, hi8(2 * 5 * 8 + 8)
212         rcall theta_2b
213 /* a[0..4][1]{0..7} ^= rol(b[2][0]{0..7}) */
214         adiw XL, 4 * 8
215         rcall theta_2b
216 /* a[0..4][21]{0..7} ^= rol(b[3][0]{0..7}) */
217         adiw XL, 4 * 8
218         rcall theta_2b
219 /* a[0..4][3]{0..7} ^= rol(b[4][0]{0..7}) */
220         adiw XL, 4 * 8
221         rcall theta_2b
222 /* a[0..4][4]{0..7} ^= rol(b[0][0]{0..7}) */
223         subi XL, lo8(4 * 5 * 8 + 8)
224         sbci XH, hi8(4 * 5 * 8 + 8)
225         rcall theta_2b
226
227 ;       ret
228 /*
229   rho & pi
230         for(i = 0; i < 5; ++i){
231                 for(j = 0; j < 5; ++j){
232                         b[(2 * i + 3 * j) % 5][j] =
233               rotate64left_code(a[j][i], pgm_read_byte(&(keccak_rotate_codes[i][j])));
234                 }
235         }
236
237    -- or --
238
239         const uint8_t* rot_code = (const uint8_t*)keccak_rotate_codes;
240     const uint8_t* idx_idx = (const uint8_t*)rho_pi_idx_table;
241     uint64_t *a_tmp = (uint64_t*)a;
242         for(i = 0; i < 25; ++i){
243                     *((uint64_t*)(((uint8_t*)b) + pgm_read_byte(idx_idx++))) =
244                 rotate64left_code(*a_tmp++, pgm_read_byte(rot_code++));
245
246         }
247
248 */
249
250 .equ B_REG_L, 6
251 .equ B_REG_H, 7
252
253         ldi r18, lo8(keccak_rotate_codes)
254         ldi r19, hi8(keccak_rotate_codes)
255         movw r2, r18
256         ldi r18, lo8(rho_pi_idx_table)
257         ldi r19, hi8(rho_pi_idx_table)
258         movw r4, r18
259         ldi r16, 25
260         mov r8, r16
261
262         pop YH
263         pop YL
264         pop B_REG_H
265         pop B_REG_L
266
267 10:
268         ld r18, Y+
269         ld r19, Y+
270         ld r20, Y+
271         ld r21, Y+
272         ld r22, Y+
273         ld r23, Y+
274         ld r24, Y+
275         ld r25, Y+
276         movw ZL, r2
277         lpm r16, Z+
278         movw r2, ZL
279         call rotate64left_code
280         movw ZL, r4
281         lpm r16, Z+
282         movw r4, ZL
283         movw XL, B_REG_L
284         add XL, r16
285         adc XH, __zero_reg__
286         st X+, r18
287         st X+, r19
288         st X+, r20
289         st X+, r21
290         st X+, r22
291         st X+, r23
292         st X+, r24
293         st X+, r25
294
295         dec r8
296         brne 10b
297
298         pop_range 28, 29
299         pop r16
300         pop_range 2, 8
301
302         ret