Imported Upstream version 3.2
[platform/upstream/nettle.git] / sparc32 / arcfour-crypt.asm
1 C sparc32/arcfour-crypt.asm
2
3 ifelse(<
4    Copyright (C) 2002, 2005 Niels Möller
5
6    This file is part of GNU Nettle.
7
8    GNU Nettle is free software: you can redistribute it and/or
9    modify it under the terms of either:
10
11      * the GNU Lesser General Public License as published by the Free
12        Software Foundation; either version 3 of the License, or (at your
13        option) any later version.
14
15    or
16
17      * the GNU General Public License as published by the Free
18        Software Foundation; either version 2 of the License, or (at your
19        option) any later version.
20
21    or both in parallel, as here.
22
23    GNU Nettle is distributed in the hope that it will be useful,
24    but WITHOUT ANY WARRANTY; without even the implied warranty of
25    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
26    General Public License for more details.
27
28    You should have received copies of the GNU General Public License and
29    the GNU Lesser General Public License along with this program.  If
30    not, see http://www.gnu.org/licenses/.
31 >)
32
33 C       Define to YES, to enable the complex code to special case SRC
34 C       and DST with compatible alignment.
35         
36 define(<WITH_ALIGN>, <YES>)
37
38 C       Registers
39
40 define(<CTX>,   <%i0>)
41 define(<LENGTH>,<%i1>)
42 define(<DST>,   <%i2>)
43 define(<SRC>,   <%i3>)
44
45 define(<I1>,    <%i4>)
46 define(<I2>,    <%i5>)
47 define(<J>,     <%g1>)
48 define(<SI>,    <%g2>)
49 define(<SJ>,    <%g3>)
50 define(<TMP>,   <%o0>)
51 define(<TMP2>,  <%o1>)
52 define(<N>,     <%o2>)
53 define(<DATA>,  <%o3>)
54
55 C       Computes the next byte of the key stream. As input, i must
56 C       already point to the index for the current access, the index
57 C       for the next access is stored in ni. The resulting key byte is
58 C       stored in res.
59 C       ARCFOUR_BYTE(i, ni, res)
60 define(<ARCFOUR_BYTE>, <
61         ldub    [CTX + $1], SI
62         add     $1, 1, $2
63         add     J, SI, J
64         and     J, 0xff, J
65         ldub    [CTX + J], SJ
66         and     $2, 0xff, $2
67         stb     SI, [CTX + J]
68         add     SI, SJ, SI
69         and     SI, 0xff, SI
70         stb     SJ, [CTX + $1]
71         ldub    [CTX + SI], $3
72 >)dnl
73                         
74 C       FIXME: Consider using the callers window
75 define(<FRAME_SIZE>, 104)
76
77         .file "arcfour-crypt.asm"
78
79         C arcfour_crypt(struct arcfour_ctx *ctx,
80         C               size_t length, uint8_t *dst,
81         C               const uint8_t *src)
82
83         .section        ".text"
84         .align 16
85         .proc   020
86         
87 PROLOGUE(nettle_arcfour_crypt)
88
89         save    %sp, -FRAME_SIZE, %sp
90         cmp     LENGTH, 0
91         be      .Lend
92         nop
93         
94         C       Load both I and J
95         lduh    [CTX + ARCFOUR_I], I1
96         and     I1, 0xff, J
97         srl     I1, 8, I1
98
99         C       We want an even address for DST
100         andcc   DST, 1, %g0
101         add     I1, 1 ,I1
102         beq     .Laligned2
103         and     I1, 0xff, I1
104
105         mov     I1, I2
106         ldub    [SRC], DATA
107         ARCFOUR_BYTE(I2, I1, TMP)
108         subcc   LENGTH, 1, LENGTH
109         add     SRC, 1, SRC
110         xor     DATA, TMP, DATA
111         stb     DATA, [DST]
112         beq     .Ldone
113         add     DST, 1, DST
114
115 .Laligned2:
116
117         cmp     LENGTH, 2
118         blu     .Lfinal1
119         C       Harmless delay slot instruction 
120         andcc   DST, 2, %g0
121         beq     .Laligned4
122         nop
123
124         ldub    [SRC], DATA
125         ARCFOUR_BYTE(I1, I2, TMP)
126         ldub    [SRC + 1], TMP2
127         add     SRC, 2, SRC
128         xor     DATA, TMP, DATA
129         sll     DATA, 8, DATA   
130
131         ARCFOUR_BYTE(I2, I1, TMP)
132         xor     TMP2, TMP, TMP
133         subcc   LENGTH, 2, LENGTH
134         or      DATA, TMP, DATA
135
136         sth     DATA, [DST]
137         beq     .Ldone
138         add     DST, 2, DST
139         
140 .Laligned4:
141         cmp     LENGTH, 4
142         blu     .Lfinal2
143         C       Harmless delay slot instruction
144         srl     LENGTH, 2, N
145         
146 .Loop:
147         C       Main loop, with aligned writes
148         
149         C       FIXME: Could check if SRC is aligned, and
150         C       use 32-bit reads in that case.
151
152         ldub    [SRC], DATA
153         ARCFOUR_BYTE(I1, I2, TMP)
154         ldub    [SRC + 1], TMP2
155         xor     TMP, DATA, DATA
156         sll     DATA, 8, DATA
157
158         ARCFOUR_BYTE(I2, I1, TMP)
159         xor     TMP2, TMP, TMP
160         ldub    [SRC + 2], TMP2
161         or      TMP, DATA, DATA
162         sll     DATA, 8, DATA
163
164         ARCFOUR_BYTE(I1, I2, TMP)
165         xor     TMP2, TMP, TMP
166         ldub    [SRC + 3], TMP2
167         or      TMP, DATA, DATA
168         sll     DATA, 8, DATA
169
170         ARCFOUR_BYTE(I2, I1, TMP)
171         xor     TMP2, TMP, TMP
172         or      TMP, DATA, DATA
173         subcc   N, 1, N
174         add     SRC, 4, SRC
175         st      DATA, [DST]
176         bne     .Loop
177         add     DST, 4, DST
178         
179         andcc   LENGTH, 3, LENGTH
180         beq     .Ldone
181         nop
182
183 .Lfinal2:
184         C       DST address must be 2-aligned
185         cmp     LENGTH, 2
186         blu     .Lfinal1
187         nop
188
189         ldub    [SRC], DATA
190         ARCFOUR_BYTE(I1, I2, TMP)
191         ldub    [SRC + 1], TMP2
192         add     SRC, 2, SRC
193         xor     DATA, TMP, DATA
194         sll     DATA, 8, DATA   
195
196         ARCFOUR_BYTE(I2, I1, TMP)
197         xor     TMP2, TMP, TMP
198         or      DATA, TMP, DATA
199
200         sth     DATA, [DST]
201         beq     .Ldone
202         add     DST, 2, DST
203
204 .Lfinal1:
205         mov     I1, I2
206         ldub    [SRC], DATA
207         ARCFOUR_BYTE(I2, I1, TMP)
208         xor     DATA, TMP, DATA
209         stb     DATA, [DST]
210
211 .Ldone:
212         C       Save back I and J
213         sll     I2, 8, I2
214         or      I2, J, I2
215         stuh    I2, [CTX + ARCFOUR_I]
216
217 .Lend:
218         ret
219         restore
220
221 EPILOGUE(nettle_arcfour_crypt)
222
223 C Some stats from adriana.lysator.liu.se (SS1000E, 85 MHz), for AES 128
224
225 C 1:    nettle-1.13 C-code
226 C 2:    First working version of the assembler code
227 C 3:    Moved load of source byte
228 C 4:    Better instruction scheduling
229 C 5:    Special case SRC and DST with compatible alignment
230 C 6:    After bugfix (reorder of ld [CTX+SI+SJ] and st [CTX + SI])
231 C 7:    Unrolled only twice, with byte-accesses
232 C 8:    Unrolled, using 8-bit reads and aligned 32-bit writes.
233
234 C       MB/s    cycles/byte     Code size (bytes)
235 C 1:    6.6     12.4            132
236 C 2:    5.6     14.5            116
237 C 3:    6.0     13.5            116
238 C 4:    6.5     12.4            116
239 C 5:    7.9     10.4            496
240 C 6:    8.3     9.7             496
241 C 7:    6.7     12.1            268
242 C 8:    8.3     9.8             768