]> git.cryptolib.org Git - avr-crypto-lib.git/blob - keccak/keccak-asm.S
9ccd79e0d8c9d3d7c6dafdb0c09b119620276347
[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         void keccak_theta (uint64_t *a, uint64_t *b){
35         // uint64_t b[5][5];
36                 for(i = 0; i < 5; ++i){
37                         b[i][0] = a[0][i] ^ a[1][i] ^ a[2][i] ^ a[3][i] ^ a[4][i];
38                 }
39         }
40 */
41
42 /*********************************************
43  * theta_2a
44  *********************************************
45         input:
46                 r24:r25 = a ; uint64_t a[5][5]
47                 X = b       ; uint64_t *b
48         output:
49                 a[0..4][0] ^= b
50                 r20 = 0
51                 r21 = XX
52                 r22 = XX
53                 r24:r25 += 8
54                 X += 8
55                 Z = r24:r25 + 7 + 4 * 40
56 */
57 theta_2a:
58         ldi r20, 8
59 10:
60         movw ZL, r24
61         ld  r21, X+
62         .irp r, 0, 1, 2, 3, 4
63                 ld  r22, Z
64                 eor r22, r21
65                 st  Z, r22
66         .if \r != 4
67                 adiw ZL, 40
68         .endif
69         .endr
70         adiw r24, 1
71         dec r20
72         brne 10b
73         ret
74
75 /*********************************************
76  * theta_2b
77  *********************************************
78         input:
79                 r24:r25 = a+1 ; uint64_t a[5][5]
80                 X = b       ; uint64_t *b
81         output:
82                 a[0..4][0] ^= rol(b,1)
83                 r19 = XX
84                 r20 = 0
85                 r21 = XX
86                 r22 = XX
87                 r24:r25 += 8
88                 X += 8
89                 Z = r24:r25 + 7 + 4 * 40
90 */
91 theta_2b:
92         ldi r20, 7
93         ld r19, X+
94         lsl r19
95         rol __zero_reg__
96 10:
97         movw ZL, r24
98         ld  r21, X+
99         ror __zero_reg__
100         rol r21
101         rol __zero_reg__
102         .irp r, 0, 1, 2, 3, 4
103                 ld  r22, Z
104                 eor r22, r21
105                 st  Z, r22
106         .if \r != 4
107                 adiw ZL, 40
108         .endif
109         .endr
110         adiw r24, 1
111         dec r20
112         brne 10b
113         add r19, __zero_reg__
114         sbiw r24, 8
115         movw ZL, r24
116         .irp r, 0, 1, 2, 3, 4
117                 ld  r22, Z
118                 eor r22, r19
119                 st  Z, r22
120         .if \r != 4
121                 adiw ZL, 40
122         .endif
123         .endr
124         adiw r24, 9
125         clr __zero_reg__
126         ret
127
128
129 .global keccak_theta
130 keccak_theta:
131         movw r30, r24 ; Z = a
132         movw r26, r22 ; X = b
133         ldi r19, 5
134 10:
135         ldi r20, 8
136 20:
137         ld  r22, Z
138         adiw ZL, 40
139         ld  r21, Z
140         eor r22, r21
141         adiw ZL, 40
142         ld  r21, Z
143         eor r22, r21
144         adiw ZL, 40
145         ld  r21, Z
146         eor r22, r21
147         adiw ZL, 40
148         ld  r21, Z
149         eor r22, r21
150         adiw r24, 1
151         movw r30, r24
152         st X+, r22
153         dec r20
154         brne 20b
155
156         adiw XL, 8 * 4
157         dec r19
158         brne 10b
159 /*
160         for(i = 0; i < 5; ++i){
161                 for(j = 0; j < 5; ++j){
162                         a[j][i] ^= b[(4 + i) % 5][0];
163                 }
164         }
165
166 */
167 /* a[0..4][0]{0..7} ^= b[4][0]{0..7} */
168         sbiw XL, 5 * 8
169         sbiw r24, 40
170         rcall theta_2a
171 /* a[0..4][1]{0..7} ^= b[0][0]{0..7} */
172         subi XL, lo8(4 * 5 * 8 + 8)
173         sbci XH, hi8(4 * 5 * 8 + 8)
174         rcall theta_2a
175 /* a[0..4][2]{0..7} ^= b[1][0]{0..7} */
176         adiw XL, 4 * 8
177         rcall theta_2a
178 /* a[0..4][3]{0..7} ^= b[2][0]{0..7} */
179         adiw XL, 4 * 8
180         rcall theta_2a
181 /* a[0..4][4]{0..7} ^= b[3][0]{0..7} */
182         adiw XL, 4 * 8
183         rcall theta_2a
184 /*
185         for(i = 0; i < 5; ++i){
186         for(j = 0; j < 5; ++j){
187             a[j][i] ^= rotate64_1bit_left(b[(i + 1) % 5][0]);
188         }
189     }
190 */
191 /* a[0..4][0]{0..7} ^= rol(b[1][0]{0..7}) */
192         subi r24, lo8(5 * 8 - 1)
193         sbci r25, hi8(5 * 8 - 1)
194         subi XL, lo8(2 * 5 * 8 + 8)
195         sbci XH, hi8(2 * 5 * 8 + 8)
196         rcall theta_2b
197 /* a[0..4][1]{0..7} ^= rol(b[2][0]{0..7}) */
198         adiw XL, 4 * 8
199         rcall theta_2b
200 /* a[0..4][21]{0..7} ^= rol(b[3][0]{0..7}) */
201         adiw XL, 4 * 8
202         rcall theta_2b
203 /* a[0..4][3]{0..7} ^= rol(b[4][0]{0..7}) */
204         adiw XL, 4 * 8
205         rcall theta_2b
206 /* a[0..4][4]{0..7} ^= rol(b[0][0]{0..7}) */
207         subi XL, lo8(4 * 5 * 8 + 8)
208         sbci XH, hi8(4 * 5 * 8 + 8)
209         rcall theta_2b
210
211
212         ret