]> git.cryptolib.org Git - avr-crypto-lib.git/blob - keccak/keccak-asm.S
[keccak-asm] chi 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 ;       a[i][j] =  b[i][j] ^ ((~(b[i][(j + 1) % 5])) & (b[i][(j + 2) % 5]));
139
140 /*********************************************
141  * chi_step
142  *********************************************
143         input:
144                 Y = a; uint8t *a;
145                 X = b; uint8t *b;
146                 Z = c; uint8t *c;
147         output:
148                 a[0..7] ^= ~b[0..7] & c[0..7]
149                 X += 8
150                 Y += 8
151                 Z += 8
152                 r16 = 0
153                 trash r21, r22, r23
154 */
155 chi_step:
156         ldi r16, 8
157 10:
158         ld r21, Y
159         ld r22, X+
160         ld r23, Z+
161         com r22
162         and r22, r23
163         eor r21, r22
164         st Y+, r21
165         dec r16
166         brne 10b
167         ret
168
169 .global keccak_theta
170 keccak_theta:
171         push_range 2, 8
172         push r16
173         push_range 28, 29
174
175         movw r30, r24 ; Z = a
176         movw r26, r22 ; X = b
177
178         ldi r19, 5
179 10:
180         ldi r20, 8
181 20:
182         ld  r22, Z
183         adiw ZL, 40
184         ld  r21, Z
185         eor r22, r21
186         adiw ZL, 40
187         ld  r21, Z
188         eor r22, r21
189         adiw ZL, 40
190         ld  r21, Z
191         eor r22, r21
192         adiw ZL, 40
193         ld  r21, Z
194         eor r22, r21
195         adiw r24, 1
196         movw r30, r24
197         st X+, r22
198         dec r20
199         brne 20b
200
201         adiw XL, 8 * 4
202         dec r19
203         brne 10b
204 /*
205         for(i = 0; i < 5; ++i){
206                 for(j = 0; j < 5; ++j){
207                         a[j][i] ^= b[(4 + i) % 5][0];
208                 }
209         }
210
211 */
212 /* a[0..4][0]{0..7} ^= b[4][0]{0..7} */
213         sbiw XL, 5 * 8
214         sbiw r24, 40
215         rcall theta_2a
216 /* a[0..4][1]{0..7} ^= b[0][0]{0..7} */
217         subi XL, lo8(4 * 5 * 8 + 8)
218         sbci XH, hi8(4 * 5 * 8 + 8)
219         rcall theta_2a
220 /* a[0..4][2]{0..7} ^= b[1][0]{0..7} */
221         adiw XL, 4 * 8
222         rcall theta_2a
223 /* a[0..4][3]{0..7} ^= b[2][0]{0..7} */
224         adiw XL, 4 * 8
225         rcall theta_2a
226 /* a[0..4][4]{0..7} ^= b[3][0]{0..7} */
227         adiw XL, 4 * 8
228         rcall theta_2a
229 /*
230         for(i = 0; i < 5; ++i){
231         for(j = 0; j < 5; ++j){
232             a[j][i] ^= rotate64_1bit_left(b[(i + 1) % 5][0]);
233         }
234     }
235 */
236 /* a[0..4][0]{0..7} ^= rol(b[1][0]{0..7}) */
237         subi r24, lo8(5 * 8 - 1)
238         sbci r25, hi8(5 * 8 - 1)
239         subi XL, lo8(2 * 5 * 8 + 8)
240         sbci XH, hi8(2 * 5 * 8 + 8)
241         rcall theta_2b
242 /* a[0..4][1]{0..7} ^= rol(b[2][0]{0..7}) */
243         adiw XL, 4 * 8
244         rcall theta_2b
245 /* a[0..4][21]{0..7} ^= rol(b[3][0]{0..7}) */
246         adiw XL, 4 * 8
247         rcall theta_2b
248 /* a[0..4][3]{0..7} ^= rol(b[4][0]{0..7}) */
249         adiw XL, 4 * 8
250         rcall theta_2b
251 /* a[0..4][4]{0..7} ^= rol(b[0][0]{0..7}) */
252         subi XL, lo8(4 * 5 * 8 + 8)
253         sbci XH, hi8(4 * 5 * 8 + 8)
254         rcall theta_2b
255
256 ;       ret
257 /*
258   rho & pi
259         for(i = 0; i < 5; ++i){
260                 for(j = 0; j < 5; ++j){
261                         b[(2 * i + 3 * j) % 5][j] =
262               rotate64left_code(a[j][i], pgm_read_byte(&(keccak_rotate_codes[i][j])));
263                 }
264         }
265
266    -- or --
267
268         const uint8_t* rot_code = (const uint8_t*)keccak_rotate_codes;
269     const uint8_t* idx_idx = (const uint8_t*)rho_pi_idx_table;
270     uint64_t *a_tmp = (uint64_t*)a;
271         for(i = 0; i < 25; ++i){
272                     *((uint64_t*)(((uint8_t*)b) + pgm_read_byte(idx_idx++))) =
273                 rotate64left_code(*a_tmp++, pgm_read_byte(rot_code++));
274
275         }
276
277 */
278
279 .equ B_REG_L, 6
280 .equ B_REG_H, 7
281
282         ldi r18, lo8(keccak_rotate_codes)
283         ldi r19, hi8(keccak_rotate_codes)
284         movw r2, r18
285         ldi r18, lo8(rho_pi_idx_table)
286         ldi r19, hi8(rho_pi_idx_table)
287         movw r4, r18
288         ldi r16, 25
289         mov r8, r16
290
291         sbiw r24, 5 * 8 + 1
292         movw YL, r24
293         sbiw XL, 8
294         movw B_REG_L, XL
295
296 10:
297         ld r18, Y+
298         ld r19, Y+
299         ld r20, Y+
300         ld r21, Y+
301         ld r22, Y+
302         ld r23, Y+
303         ld r24, Y+
304         ld r25, Y+
305         movw ZL, r2
306         lpm r16, Z+
307         movw r2, ZL
308         call rotate64left_code
309         movw ZL, r4
310         lpm r16, Z+
311         movw r4, ZL
312         movw XL, B_REG_L
313         add XL, r16
314         adc XH, __zero_reg__
315         st X+, r18
316         st X+, r19
317         st X+, r20
318         st X+, r21
319         st X+, r22
320         st X+, r23
321         st X+, r24
322         st X+, r25
323
324         dec r8
325         brne 10b
326 /*
327         -- chi --
328         for(i = 0; i < 5; ++i){
329         a[i][0] ^= ((~(b[i][1])) & (b[i][2]));
330         a[i][1] ^= ((~(b[i][2])) & (b[i][3]));
331         a[i][2] ^= ((~(b[i][3])) & (b[i][4]));
332         a[i][3] ^= ((~(b[i][4])) & (b[i][0]));
333         a[i][4] ^= ((~(b[i][0])) & (b[i][1]));
334
335         }
336 */
337         ; memcpy(a, b, 200)
338         ; X points at b + 32 + 8 = b + 40 = b[1][0] has to point to b[0][0]
339         ldi r16, 200
340         sbiw XL, 5 * 8
341         movw ZL, XL
342         subi YL, lo8(5 * 5 * 8)
343         sbci YH, hi8(5 * 5 * 8)
344         movw r2, YL
345 10:
346         ld r22, X+
347         st Y+, r22
348         dec r16
349         brne 10b
350
351         ; Z points at b
352         movw XL, ZL
353         adiw XL, 8
354         adiw ZL, 16
355         movw YL, r2
356         ldi r18, 5
357 10:
358         rcall chi_step
359         rcall chi_step
360         rcall chi_step
361         sbiw ZL, 5 * 8
362         rcall chi_step
363         sbiw XL, 5 * 8
364         rcall chi_step
365         adiw XL, 5 * 8
366         adiw ZL, 5 * 8
367         dec r18
368         brne 10b
369         pop_range 28, 29
370         pop r16
371         pop_range 2, 8
372
373         ret