d6636537690695d01fc6d8f80817a294ff82134d
[platform/upstream/nettle.git] / x86_64 / serpent-encrypt.asm
1 C x86_64/serpent-encrypt.asm
2
3 ifelse(<
4    Copyright (C) 2011 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 include_src(<x86_64/serpent.m4>)
34
35 C Register usage:
36
37 C Single block serpent state, two copies
38 define(<x0>, <%eax>)
39 define(<x1>, <%ebx>)
40 define(<x2>, <%ebp>)
41 define(<x3>, <%r8d>)
42
43 define(<y0>, <%r9d>)
44 define(<y1>, <%r10d>)
45 define(<y2>, <%r11d>)
46 define(<y3>, <%r12d>)
47
48 C Quadruple block serpent state, two copies
49 define(<X0>, <%xmm0>)
50 define(<X1>, <%xmm1>)
51 define(<X2>, <%xmm2>)
52 define(<X3>, <%xmm3>)
53
54 define(<Y0>, <%xmm4>)
55 define(<Y1>, <%xmm5>)
56 define(<Y2>, <%xmm6>)
57 define(<Y3>, <%xmm7>)
58
59 define(<MINUS1>, <%xmm8>)
60 define(<T0>, <%xmm9>)
61 define(<T1>, <%xmm10>)
62 define(<T2>, <%xmm11>)
63 define(<T3>, <%xmm12>)
64
65 C Arguments
66 define(<CTX>, <%rdi>)
67 define(<N>, <%rsi>)
68 define(<DST>, <%rdx>)
69 define(<SRC>, <%rcx>)
70
71 define(<CNT>, <%r13>)
72 define(<TMP32>, <%r14d>)
73
74 C SBOX macros. Inputs $1 - $4 (destroyed), outputs $5 - $8
75
76 define(<SBOX0>, <
77         mov     $2, $8  C y3  = x1 ^ x2
78         xor     $3, $8
79         mov     $1, $5  C y0  = x0 | x3
80         or      $4, $5
81         mov     $1, $6  C y1  = x0 ^ x1
82         xor     $2, $6
83         xor     $5, $8  C y3 ^= y0
84         mov     $3, $7  C y2  = x2 | y3
85         or      $8, $7
86         xor     $4, $1  C x0 ^= x3
87         and     $4, $7  C y2 &= x3
88         xor     $3, $4  C x3 ^= x2
89         or      $2, $3  C x2 |= x1
90         mov     $6, $5  C y0  = y1 & x2
91         and     $3, $5
92         xor     $5, $7  C y2 ^= y0
93         and     $7, $5  C y0 &= y2
94         xor     $3, $5  C y0 ^= x2
95         and     $1, $2  C x1 &= x0
96         xor     $1, $5  C y0 ^= x0
97         not     $5      C y0  = ~y0
98         mov     $5, $6  C y1  = y0 ^ x1
99         xor     $2, $6
100         xor     $4, $6  C y1 ^= x3
101 >)
102
103 define(<SBOX1>, <
104         mov     $1, $6  C y1  = x0 | x3
105         or      $4, $6 
106         mov     $3, $7  C y2  = x2 ^ x3
107         xor     $4, $7
108         mov     $2, $5  C y0  = ~x1
109         not     $5
110         mov     $1, $8  C y3  = x0 ^ x2
111         xor     $3, $8
112         or      $1, $5  C y0 |= x0
113         and     $4, $8  C y3 &= x3
114         mov     $6, $1  C x0  = y1 & y2
115         and     $7, $1
116         or      $2, $8  C y3 |= x1
117         xor     $5, $7  C y2 ^= y0
118         xor     $1, $8  C y3 ^= x0
119         mov     $6, $1  C x0  = y1 ^ y3
120         xor     $8, $1
121         xor     $7, $1  C x0 ^= y2
122         mov     $2, $6  C y1  = x1 & x3
123         and     $4, $6
124         xor     $1, $6  C y1 ^= x0
125         mov     $6, $4  C x3  = y1 | y3
126         or      $8, $4
127         not     $8      C y3  = ~y3
128         and     $4, $5  C y0 &= x3
129         xor     $3, $5  C y0 ^= x2
130 >)
131
132 define(<SBOX2>, <
133         mov     $1, $7  C y2 = x1 | x2
134         or      $3, $7
135         mov     $1, $6
136         xor     $2, $6
137         mov     $4, $8
138         xor     $7, $8
139         mov     $6, $5
140         xor     $8, $5
141         or      $1, $4
142         xor     $5, $3
143         mov     $2, $1
144         xor     $3, $1
145         or      $2, $3
146         and     $7, $1
147         xor     $3, $8
148         or      $8, $6
149         xor     $1, $6
150         mov     $8, $7
151         xor     $6, $7
152         xor     $2, $7
153         not     $8
154         xor     $4, $7
155 >)
156
157 define(<SBOX3>, <
158         mov     $1, $6
159         xor     $3, $6
160         mov     $1, $5
161         or      $4, $5
162         mov     $1, $8
163         and     $4, $8
164         and     $5, $6
165         or      $2, $8
166         mov     $1, $7
167         and     $2, $7
168         or      $3, $7
169         mov     $4, $3
170         xor     $6, $3
171         xor     $8, $6
172         or      $3, $1
173         xor     $2, $3
174         and     $4, $8
175         xor     $8, $5
176         mov     $7, $8
177         xor     $3, $8
178         xor     $5, $7
179         or      $8, $4
180         and     $4, $2
181         mov     $1, $5
182         xor     $2, $5
183 >)
184
185 define(<SBOX4>, <
186         mov     $1, $8
187         or      $2, $8
188         mov     $2, $7
189         or      $3, $7
190         xor     $1, $7
191         and     $4, $8
192         mov     $2, $5
193         xor     $4, $5
194         or      $7, $4
195         and     $4, $1
196         and     $3, $2
197         xor     $8, $3
198         xor     $7, $8
199         or      $2, $7
200         mov     $8, $6
201         and     $5, $6
202         xor     $6, $7
203         xor     $5, $6
204         or      $2, $6
205         xor     $1, $6
206         and     $4, $5
207         xor     $3, $5
208         not     $5
209 >)
210
211 define(<SBOX5>, <
212         mov     $2, $5
213         or      $4, $5
214         xor     $3, $5
215         mov     $2, $3
216         xor     $4, $3
217         mov     $1, $7
218         xor     $3, $7
219         and     $3, $1
220         xor     $1, $5
221         mov     $2, $8
222         or      $7, $8
223         or      $5, $2
224         not     $5
225         or      $5, $1
226         xor     $3, $8
227         xor     $1, $8
228         mov     $4, $6
229         or      $5, $6
230         xor     $6, $4
231         xor     $7, $6
232         or      $4, $7
233         xor     $2, $7
234 >)
235
236 define(<SBOX6>, <
237         mov     $1, $5
238         xor     $4, $5
239         mov     $1, $6
240         and     $4, $6
241         mov     $1, $7
242         or      $3, $7
243         or      $2, $4
244         xor     $3, $4
245         xor     $2, $1
246         mov     $2, $8
247         or      $3, $8
248         xor     $2, $3
249         and     $5, $8
250         xor     $3, $6
251         not     $6
252         and     $6, $5
253         and     $6, $2
254         xor     $8, $2
255         xor     $4, $8
256         xor     $2, $7
257         not     $7
258         xor     $7, $5
259         xor     $1, $5
260 >)
261
262 define(<SBOX7>, <
263         mov     $1, $5
264         and     $3, $5
265         mov     $2, $8
266         or      $5, $8  C t04
267         xor     $3, $8
268         mov     $4, $6
269         not     $6      C t02   
270         and     $1, $6
271         xor     $6, $8
272         mov     $3, $6
273         or      $8, $6
274         xor     $1, $6
275         mov     $1, $7
276         and     $2, $7
277         xor     $7, $3
278         or      $4, $7
279         xor     $7, $6
280         mov     $2, $7
281         or      $5, $7  C t04
282         and     $8, $7
283         xor     $6, $2
284         or      $2, $7
285         xor     $1, $7
286         xor     $6, $5
287         not     $4      C t02
288         or      $4, $5
289         xor     $3, $5
290 >)
291
292 define(<LT>, <
293         rol     <$>13, $1
294         rol     <$>3, $3
295         xor     $1, $2
296         xor     $3, $2
297         mov     $1, TMP32
298         shl     <$>3, TMP32
299         xor     $3, $4
300         xor     TMP32, $4
301         rol     $2
302         rol     <$>7, $4
303         xor     $2, $1
304         xor     $4, $1
305         mov     $2, TMP32
306         shl     <$>7, TMP32
307         xor     $4, $3
308         xor     TMP32, $3
309         rol     <$>5, $1
310         rol     <$>22, $3
311 >)
312
313 C Parallel operation on four blocks at a time.
314
315 C pnot instruction is missing. For lack of a spare register, XOR with
316 C constant in memory.
317         
318 define(<PNOT>, <
319         pxor    MINUS1, $1
320 >)
321
322 define(<WSBOX0>, <
323         movdqa  $2, $8  C y3  = x1 ^ x2
324         pxor    $3, $8
325         movdqa  $1, $5  C y0  = x0 | x3
326         por     $4, $5
327         movdqa  $1, $6  C y1  = x0 ^ x1
328         pxor    $2, $6
329         pxor    $5, $8  C y3 ^= y0
330         movdqa  $3, $7  C y2  = x2 | y3
331         por     $8, $7
332         pxor    $4, $1  C x0 ^= x3
333         pand    $4, $7  C y2 &= x3
334         pxor    $3, $4  C x3 ^= x2
335         por     $2, $3  C x2 |= x1
336         movdqa  $6, $5  C y0  = y1 & x2
337         pand    $3, $5
338         pxor    $5, $7  C y2 ^= y0
339         pand    $7, $5  C y0 &= y2
340         pxor    $3, $5  C y0 ^= x2
341         pand    $1, $2  C x1 &= x0
342         pxor    $1, $5  C y0 ^= x0
343         PNOT($5)        C y0  = ~y0
344         movdqa  $5, $6  C y1  = y0 ^ x1
345         pxor    $2, $6
346         pxor    $4, $6  C y1 ^= x3
347 >)
348
349 define(<WSBOX1>, <
350         movdqa  $1, $6  C y1  = x0 | x3
351         por     $4, $6 
352         movdqa  $3, $7  C y2  = x2 ^ x3
353         pxor    $4, $7
354         movdqa  $2, $5  C y0  = ~x1
355         PNOT($5)
356         movdqa  $1, $8  C y3  = x0 ^ x2
357         pxor    $3, $8
358         por     $1, $5  C y0 |= x0
359         pand    $4, $8  C y3 &= x3
360         movdqa  $6, $1  C x0  = y1 & y2
361         pand    $7, $1
362         por     $2, $8  C y3 |= x1
363         pxor    $5, $7  C y2 ^= y0
364         pxor    $1, $8  C y3 ^= x0
365         movdqa  $6, $1  C x0  = y1 ^ y3
366         pxor    $8, $1
367         pxor    $7, $1  C x0 ^= y2
368         movdqa  $2, $6  C y1  = x1 & x3
369         pand    $4, $6
370         pxor    $1, $6  C y1 ^= x0
371         movdqa  $6, $4  C x3  = y1 | y3
372         por     $8, $4
373         PNOT($8)        C y3  = ~y3
374         pand    $4, $5  C y0 &= x3
375         pxor    $3, $5  C y0 ^= x2
376 >)
377
378 define(<WSBOX2>, <
379         movdqa  $1, $7  C y2 = x1 | x2
380         por     $3, $7
381         movdqa  $1, $6
382         pxor    $2, $6
383         movdqa  $4, $8
384         pxor    $7, $8
385         movdqa  $6, $5
386         pxor    $8, $5
387         por     $1, $4
388         pxor    $5, $3
389         movdqa  $2, $1
390         pxor    $3, $1
391         por     $2, $3
392         pand    $7, $1
393         pxor    $3, $8
394         por     $8, $6
395         pxor    $1, $6
396         movdqa  $8, $7
397         pxor    $6, $7
398         pxor    $2, $7
399         PNOT($8)
400         pxor    $4, $7
401 >)
402
403 define(<WSBOX3>, <
404         movdqa  $1, $6
405         pxor    $3, $6
406         movdqa  $1, $5
407         por     $4, $5
408         movdqa  $1, $8
409         pand    $4, $8
410         pand    $5, $6
411         por     $2, $8
412         movdqa  $1, $7
413         pand    $2, $7
414         por     $3, $7
415         movdqa  $4, $3
416         pxor    $6, $3
417         pxor    $8, $6
418         por     $3, $1
419         pxor    $2, $3
420         pand    $4, $8
421         pxor    $8, $5
422         movdqa  $7, $8
423         pxor    $3, $8
424         pxor    $5, $7
425         por     $8, $4
426         pand    $4, $2
427         movdqa  $1, $5
428         pxor    $2, $5
429 >)
430
431 define(<WSBOX4>, <
432         movdqa  $1, $8
433         por     $2, $8
434         movdqa  $2, $7
435         por     $3, $7
436         pxor    $1, $7
437         pand    $4, $8
438         movdqa  $2, $5
439         pxor    $4, $5
440         por     $7, $4
441         pand    $4, $1
442         pand    $3, $2
443         pxor    $8, $3
444         pxor    $7, $8
445         por     $2, $7
446         movdqa  $8, $6
447         pand    $5, $6
448         pxor    $6, $7
449         pxor    $5, $6
450         por     $2, $6
451         pxor    $1, $6
452         pand    $4, $5
453         pxor    $3, $5
454         PNOT($5)
455 >)
456
457 define(<WSBOX5>, <
458         movdqa  $2, $5
459         por     $4, $5
460         pxor    $3, $5
461         movdqa  $2, $3
462         pxor    $4, $3
463         movdqa  $1, $7
464         pxor    $3, $7
465         pand    $3, $1
466         pxor    $1, $5
467         movdqa  $2, $8
468         por     $7, $8
469         por     $5, $2
470         PNOT($5)
471         por     $5, $1
472         pxor    $3, $8
473         pxor    $1, $8
474         movdqa  $4, $6
475         por     $5, $6
476         pxor    $6, $4
477         pxor    $7, $6
478         por     $4, $7
479         pxor    $2, $7
480 >)
481
482 define(<WSBOX6>, <
483         movdqa  $1, $5
484         pxor    $4, $5
485         movdqa  $1, $6
486         pand    $4, $6
487         movdqa  $1, $7
488         por     $3, $7
489         por     $2, $4
490         pxor    $3, $4
491         pxor    $2, $1
492         movdqa  $2, $8
493         por     $3, $8
494         pxor    $2, $3
495         pand    $5, $8
496         pxor    $3, $6
497         PNOT($6)
498         pand    $6, $5
499         pand    $6, $2
500         pxor    $8, $2
501         pxor    $4, $8
502         pxor    $2, $7
503         PNOT($7)
504         pxor    $7, $5
505         pxor    $1, $5
506 >)
507
508 define(<WSBOX7>, <
509         movdqa  $1, $5
510         pand    $3, $5
511         movdqa  $2, $8
512         por     $5, $8  C t04
513         pxor    $3, $8
514         movdqa  $4, $6
515         pandn   $1, $6  C t02 implicit
516         pxor    $6, $8
517         movdqa  $3, $6
518         por     $8, $6
519         pxor    $1, $6
520         movdqa  $1, $7
521         pand    $2, $7
522         pxor    $7, $3
523         por     $4, $7
524         pxor    $7, $6
525         movdqa  $2, $7
526         por     $5, $7  C t04
527         pand    $8, $7
528         pxor    $6, $2
529         por     $2, $7
530         pxor    $1, $7
531         pxor    $6, $5
532         PNOT($4)        C t02
533         por     $4, $5
534         pxor    $3, $5
535 >)
536
537 C WLT(x0, x1, x2, x3)
538 define(<WLT>, <
539         WROL(13, $1)
540         WROL(3, $3)
541         pxor    $1, $2
542         pxor    $3, $2
543         movdqa  $1, T0
544         pslld   <$>3, T0
545         pxor    $3, $4
546         pxor    T0, $4
547         WROL(1, $2)
548         WROL(7, $4)
549         pxor    $2, $1
550         pxor    $4, $1
551         movdqa  $2, T0
552         pslld   <$>7, T0
553         pxor    $4, $3
554         pxor    T0, $3
555         WROL(5, $1)
556         WROL(22, $3)
557 >)
558
559         .file "serpent-encrypt.asm"
560         
561         C serpent_encrypt(struct serpent_context *ctx, 
562         C                 size_t length, uint8_t *dst,
563         C                 const uint8_t *src)
564         .text
565         ALIGN(16)
566 PROLOGUE(nettle_serpent_encrypt)
567         C save all registers that need to be saved
568         W64_ENTRY(4, 13)
569         push    %rbx
570         push    %rbp
571         push    %r12
572         push    %r13
573         push    %r14
574
575         lea     (SRC, N), SRC
576         lea     (DST, N), DST
577         neg     N
578         jz      .Lend
579
580         C Point at the final subkey.
581         lea     512(CTX), CTX
582
583         cmp     $-64, N
584         ja      .Lblock_loop
585
586         pcmpeqd MINUS1, MINUS1
587
588 .Lwblock_loop:
589         movups  (SRC, N), X0
590         movups  16(SRC, N), X1
591         movups  32(SRC, N), X2
592         movups  48(SRC, N), X3
593
594         WTRANSPOSE(X0, X1, X2, X3)
595
596         mov     $-512, CNT
597         jmp     .Lwround_start
598
599         ALIGN(16)
600 .Lwround_loop:
601         WLT(X0,X1,X2,X3)
602 .Lwround_start:
603         WKEYXOR(, X0,X1,X2,X3)
604         WSBOX0(X0,X1,X2,X3, Y0,Y1,Y2,Y3)
605         WLT(Y0,Y1,Y2,Y3)
606
607         WKEYXOR(16, Y0,Y1,Y2,Y3)
608         WSBOX1(Y0,Y1,Y2,Y3, X0,X1,X2,X3)
609         WLT(X0,X1,X2,X3)
610
611         WKEYXOR(32, X0,X1,X2,X3)
612         WSBOX2(X0,X1,X2,X3, Y0,Y1,Y2,Y3)
613         WLT(Y0,Y1,Y2,Y3)
614
615         WKEYXOR(48, Y0,Y1,Y2,Y3)
616         WSBOX3(Y0,Y1,Y2,Y3, X0,X1,X2,X3)
617         WLT(X0,X1,X2,X3)
618
619         WKEYXOR(64, X0,X1,X2,X3)
620         WSBOX4(X0,X1,X2,X3, Y0,Y1,Y2,Y3)
621         WLT(Y0,Y1,Y2,Y3)
622
623         WKEYXOR(80, Y0,Y1,Y2,Y3)
624         WSBOX5(Y0,Y1,Y2,Y3, X0,X1,X2,X3)
625         WLT(X0,X1,X2,X3)
626
627         WKEYXOR(96, X0,X1,X2,X3)
628         WSBOX6(X0,X1,X2,X3, Y0,Y1,Y2,Y3)
629         WLT(Y0,Y1,Y2,Y3)
630
631         WKEYXOR(112, Y0,Y1,Y2,Y3)
632         WSBOX7(Y0,Y1,Y2,Y3, X0,X1,X2,X3)
633         add     $128, CNT
634         jnz     .Lwround_loop
635
636         C FIXME: CNT known to be zero, no index register needed
637         WKEYXOR(, X0,X1,X2,X3)
638
639         WTRANSPOSE(X0,X1,X2,X3)
640
641         movups  X0, (DST, N)
642         movups  X1, 16(DST, N)
643         movups  X2, 32(DST, N)
644         movups  X3, 48(DST, N)
645
646         C FIXME: Adjust N, so we can use just jnc without an extra cmp.
647         add     $64, N
648         jz      .Lend
649
650         cmp     $-64, N
651         jbe     .Lwblock_loop
652
653 C The single-block loop here is slightly slower than the double-block
654 C loop in serpent-encrypt.c.
655
656 C FIXME: Should use non-sse2 code only if we have a single block left.
657 C With two or three blocks, it should be better to do them in
658 C parallell.
659         
660 .Lblock_loop:
661         movl    (SRC, N), x0
662         movl    4(SRC, N), x1
663         movl    8(SRC, N), x2
664         movl    12(SRC, N), x3
665
666         mov     $-512, CNT
667         jmp     .Lround_start
668         
669         ALIGN(16)
670 .Lround_loop:
671         LT(x0,x1,x2,x3)
672 .Lround_start:
673         xor       (CTX, CNT), x0
674         xor      4(CTX, CNT), x1
675         xor      8(CTX, CNT), x2
676         xor     12(CTX, CNT), x3
677         SBOX0(x0,x1,x2,x3, y0,y1,y2,y3)
678         LT(y0,y1,y2,y3)
679         
680         xor     16(CTX, CNT), y0
681         xor     20(CTX, CNT), y1
682         xor     24(CTX, CNT), y2
683         xor     28(CTX, CNT), y3
684         SBOX1(y0,y1,y2,y3, x0,x1,x2,x3)
685         LT(x0,x1,x2,x3)
686
687         xor     32(CTX, CNT), x0
688         xor     36(CTX, CNT), x1
689         xor     40(CTX, CNT), x2
690         xor     44(CTX, CNT), x3
691         SBOX2(x0,x1,x2,x3, y0,y1,y2,y3)
692         LT(y0,y1,y2,y3)
693
694         xor     48(CTX, CNT), y0
695         xor     52(CTX, CNT), y1
696         xor     56(CTX, CNT), y2
697         xor     60(CTX, CNT), y3
698         SBOX3(y0,y1,y2,y3, x0,x1,x2,x3)
699         LT(x0,x1,x2,x3)
700
701         xor     64(CTX, CNT), x0
702         xor     68(CTX, CNT), x1
703         xor     72(CTX, CNT), x2
704         xor     76(CTX, CNT), x3
705         SBOX4(x0,x1,x2,x3, y0,y1,y2,y3)
706         LT(y0,y1,y2,y3)
707
708         xor     80(CTX, CNT), y0
709         xor     84(CTX, CNT), y1
710         xor     88(CTX, CNT), y2
711         xor     92(CTX, CNT), y3
712         SBOX5(y0,y1,y2,y3, x0,x1,x2,x3)
713         LT(x0,x1,x2,x3)
714
715         xor     96(CTX, CNT), x0
716         xor     100(CTX, CNT), x1
717         xor     104(CTX, CNT), x2
718         xor     108(CTX, CNT), x3
719         SBOX6(x0,x1,x2,x3, y0,y1,y2,y3)
720         LT(y0,y1,y2,y3)
721
722         xor     112(CTX, CNT), y0
723         xor     116(CTX, CNT), y1
724         xor     120(CTX, CNT), y2
725         xor     124(CTX, CNT), y3
726         SBOX7(y0,y1,y2,y3, x0,x1,x2,x3)
727         add     $128, CNT
728         jnz     .Lround_loop
729
730         C Apply final subkey.
731         xor       (CTX, CNT), x0
732         xor      4(CTX, CNT), x1
733         xor      8(CTX, CNT), x2
734         xor     12(CTX, CNT), x3
735
736         movl    x0, (DST, N)
737         movl    x1, 4(DST, N)
738         movl    x2, 8(DST, N)
739         movl    x3, 12(DST, N)
740         add     $16, N
741         jnc     .Lblock_loop
742
743 .Lend:
744         pop     %r14
745         pop     %r13
746         pop     %r12
747         pop     %rbp
748         pop     %rbx
749         W64_EXIT(4, 13)
750         ret